Wide sweeping changes to get RI structures working in server mode
This commit is contained in:
parent
8b65a9aedf
commit
8a86ad5e76
|
@ -75,7 +75,7 @@ public class GenericClientExample {
|
||||||
// resource, the OperationOutcome response, etc. (assuming that
|
// resource, the OperationOutcome response, etc. (assuming that
|
||||||
// any of these things were provided by the server! They may not
|
// any of these things were provided by the server! They may not
|
||||||
// always be)
|
// always be)
|
||||||
IdDt id = outcome.getId();
|
IdDt id = (IdDt) outcome.getId();
|
||||||
System.out.println("Got ID: " + id.getValue());
|
System.out.println("Got ID: " + id.getValue());
|
||||||
// END SNIPPET: create
|
// END SNIPPET: create
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ public class GenericClientExample {
|
||||||
Boolean created = outcome.getCreated();
|
Boolean created = outcome.getCreated();
|
||||||
|
|
||||||
// The ID of the created, or the pre-existing resource
|
// The ID of the created, or the pre-existing resource
|
||||||
IdDt id = outcome.getId();
|
IdDt id = (IdDt) outcome.getId();
|
||||||
// END SNIPPET: createConditional
|
// END SNIPPET: createConditional
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -149,7 +149,7 @@ public class GenericClientExample {
|
||||||
// resource, the OperationOutcome response, etc. (assuming that
|
// resource, the OperationOutcome response, etc. (assuming that
|
||||||
// any of these things were provided by the server! They may not
|
// any of these things were provided by the server! They may not
|
||||||
// always be)
|
// always be)
|
||||||
IdDt id = outcome.getId();
|
IdDt id = (IdDt) outcome.getId();
|
||||||
System.out.println("Got ID: " + id.getValue());
|
System.out.println("Got ID: " + id.getValue());
|
||||||
// END SNIPPET: update
|
// END SNIPPET: update
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<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">
|
<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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
@ -10,9 +11,42 @@
|
||||||
|
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<name>HAPI FHIR - Deployable Artifact Parent POM</name>
|
<name>HAPI FHIR - Deployable Artifact Parent POM</name>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>animal-sniffer-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>check-java-api</id>
|
||||||
|
<phase>test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<signature>
|
||||||
|
<groupId>org.codehaus.mojo.signature
|
||||||
|
</groupId>
|
||||||
|
<artifactId>java16</artifactId>
|
||||||
|
<version>1.1</version>
|
||||||
|
</signature>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.ow2.asm</groupId>
|
||||||
|
<artifactId>asm-all</artifactId>
|
||||||
|
<version>5.0.4</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
<reporting>
|
<reporting>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|
|
@ -20,10 +20,17 @@
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>${junit_version}</version>
|
<version>${junit_version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Use an older version of SLF4j -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>1.6.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-simple</artifactId>
|
<artifactId>slf4j-simple</artifactId>
|
||||||
<version>1.7.7</version>
|
<version>1.6.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -127,3 +127,5 @@ local.properties
|
||||||
# TeXlipse plugin
|
# TeXlipse plugin
|
||||||
.texlipse
|
.texlipse
|
||||||
|
|
||||||
|
/target/
|
||||||
|
/target/
|
||||||
|
|
|
@ -693,7 +693,9 @@ class ModelScanner {
|
||||||
resourceDef = new RuntimePrimitiveDatatypeDefinition(theDatatypeDefinition, theClass, isStandardType(theClass));
|
resourceDef = new RuntimePrimitiveDatatypeDefinition(theDatatypeDefinition, theClass, isStandardType(theClass));
|
||||||
}
|
}
|
||||||
myClassToElementDefinitions.put(theClass, resourceDef);
|
myClassToElementDefinitions.put(theClass, resourceDef);
|
||||||
myNameToElementDefinitions.put(resourceName, resourceDef);
|
if (!theDatatypeDefinition.isSpecialization()) {
|
||||||
|
myNameToElementDefinitions.put(resourceName, resourceDef);
|
||||||
|
}
|
||||||
|
|
||||||
return resourceName;
|
return resourceName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,11 @@ package ca.uhn.fhir.model.api;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
import org.hl7.fhir.instance.model.api.IBase;
|
import org.hl7.fhir.instance.model.api.IBase;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
|
@ -56,4 +58,6 @@ public interface IFhirVersion {
|
||||||
|
|
||||||
IVersionSpecificBundleFactory newBundleFactory(FhirContext theContext);
|
IVersionSpecificBundleFactory newBundleFactory(FhirContext theContext);
|
||||||
|
|
||||||
|
IPrimitiveType<Date> getLastUpdated(IBaseResource theResource);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.apache.http.client.methods.HttpGet;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseReference;
|
import org.hl7.fhir.instance.model.api.IBaseReference;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.BaseIdentifiableElement;
|
import ca.uhn.fhir.model.api.BaseIdentifiableElement;
|
||||||
|
@ -56,25 +57,30 @@ public abstract class BaseResourceReferenceDt extends BaseIdentifiableElement im
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param theResource
|
* @param theResource
|
||||||
* The loaded resource itself
|
* The loaded resource itself
|
||||||
*/
|
*/
|
||||||
public BaseResourceReferenceDt(IResource theResource) {
|
public BaseResourceReferenceDt(IResource theResource) {
|
||||||
myResource = theResource;
|
myResource = theResource;
|
||||||
setReference(theResource.getId());
|
setReference(theResource.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public abstract StringDt getDisplayElement();
|
public abstract StringDt getDisplayElement();
|
||||||
|
|
||||||
public abstract IdDt getReference();
|
public abstract IdDt getReference();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the actual loaded and parsed resource instance, <b>if it is already present</b>. This method will return the resource instance only if it has previously been loaded using
|
* Gets the actual loaded and parsed resource instance, <b>if it is already present</b>. This method will return the
|
||||||
* {@link #loadResource(IRestfulClient)} or it was contained within the resource containing this resource.
|
* resource instance only if it has previously been loaded using {@link #loadResource(IRestfulClient)} or it was
|
||||||
|
* contained within the resource containing this resource.
|
||||||
*
|
*
|
||||||
* See the FHIR specification section on <a href="http://www.hl7.org/implement/standards/fhir/references.html#id">contained resources</a> for more information.
|
* See the FHIR specification section on <a
|
||||||
|
* href="http://www.hl7.org/implement/standards/fhir/references.html#id">contained resources</a> for more
|
||||||
|
* information.
|
||||||
*
|
*
|
||||||
* @see #loadResource(IRestfulClient)
|
* @see #loadResource(IRestfulClient)
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public IBaseResource getResource() {
|
public IBaseResource getResource() {
|
||||||
return myResource;
|
return myResource;
|
||||||
}
|
}
|
||||||
|
@ -85,8 +91,9 @@ public abstract class BaseResourceReferenceDt extends BaseIdentifiableElement im
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the referenced resource, fetching it <b>if it has not already been loaded</b>. This method invokes the HTTP client to retrieve the resource unless it has already been loaded, or was a
|
* Returns the referenced resource, fetching it <b>if it has not already been loaded</b>. This method invokes the
|
||||||
* contained resource in which case it is simply returned.
|
* HTTP client to retrieve the resource unless it has already been loaded, or was a contained resource in which case
|
||||||
|
* it is simply returned.
|
||||||
*/
|
*/
|
||||||
public IBaseResource loadResource(IRestfulClient theClient) throws IOException {
|
public IBaseResource loadResource(IRestfulClient theClient) throws IOException {
|
||||||
if (myResource != null) {
|
if (myResource != null) {
|
||||||
|
@ -116,7 +123,7 @@ public abstract class BaseResourceReferenceDt extends BaseIdentifiableElement im
|
||||||
IParser parser = context.newXmlParser();
|
IParser parser = context.newXmlParser();
|
||||||
|
|
||||||
Reader responseReader = BaseClient.createReaderFromResponse(response);
|
Reader responseReader = BaseClient.createReaderFromResponse(response);
|
||||||
myResource = (IResource) parser.parseResource(responseReader);
|
myResource = parser.parseResource(responseReader);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
if (response instanceof CloseableHttpResponse) {
|
if (response instanceof CloseableHttpResponse) {
|
||||||
|
@ -129,6 +136,18 @@ public abstract class BaseResourceReferenceDt extends BaseIdentifiableElement im
|
||||||
|
|
||||||
public abstract BaseResourceReferenceDt setReference(IdDt theReference);
|
public abstract BaseResourceReferenceDt setReference(IdDt theReference);
|
||||||
|
|
||||||
|
public BaseResourceReferenceDt setReference(IIdType theReference) {
|
||||||
|
if (theReference instanceof IdDt) {
|
||||||
|
setReference((IdDt) theReference);
|
||||||
|
} else if (theReference != null) {
|
||||||
|
setReference(new IdDt(theReference.getValue()));
|
||||||
|
} else {
|
||||||
|
setReference((IdDt) null);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setResource(IBaseResource theResource) {
|
public void setResource(IBaseResource theResource) {
|
||||||
myResource = theResource;
|
myResource = theResource;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,15 @@ package ca.uhn.fhir.model.base.resource;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.BaseIdentifiableElement;
|
import ca.uhn.fhir.model.api.BaseIdentifiableElement;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.api.IResourceBlock;
|
import ca.uhn.fhir.model.api.IResourceBlock;
|
||||||
import ca.uhn.fhir.model.primitive.CodeDt;
|
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||||
import ca.uhn.fhir.model.primitive.StringDt;
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
|
|
||||||
public interface BaseOperationOutcome extends IResource {
|
public interface BaseOperationOutcome extends IResource, IBaseOperationOutcome {
|
||||||
|
|
||||||
public abstract BaseIssue addIssue();
|
public abstract BaseIssue addIssue();
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum;
|
import ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum;
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.context.RuntimeChildChoiceDefinition;
|
import ca.uhn.fhir.context.RuntimeChildChoiceDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
|
@ -353,6 +354,9 @@ public abstract class BaseParser implements IParser {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Bundle parseBundle(Reader theReader) {
|
public Bundle parseBundle(Reader theReader) {
|
||||||
|
if (myContext.getVersion().getVersion() == FhirVersionEnum.DSTU2_HL7ORG) {
|
||||||
|
throw new IllegalStateException("Can't parse DSTU1 (Atom) bundle in HL7.org DSTU2 mode. Use parseResource(Bundle.class, foo) instead.");
|
||||||
|
}
|
||||||
return parseBundle(null, theReader);
|
return parseBundle(null, theReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,8 @@ import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||||
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
|
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
|
||||||
|
@ -77,7 +78,7 @@ public @interface Search {
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
// NB: Read, Search (maybe others) share this annotation method, so update the javadocs everywhere
|
// NB: Read, Search (maybe others) share this annotation method, so update the javadocs everywhere
|
||||||
Class<? extends IResource> type() default IResource.class;
|
Class<? extends IBaseResource> type() default IBaseResource.class;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is an experimental option - Use with caution
|
* This is an experimental option - Use with caution
|
||||||
|
|
|
@ -20,13 +20,15 @@ package ca.uhn.fhir.rest.api;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
|
|
||||||
public class MethodOutcome {
|
public class MethodOutcome {
|
||||||
|
|
||||||
private IdDt myId;
|
private IIdType myId;
|
||||||
private BaseOperationOutcome myOperationOutcome;
|
private IBaseOperationOutcome myOperationOutcome;
|
||||||
private IdDt myVersionId;
|
private IdDt myVersionId;
|
||||||
private Boolean myCreated;
|
private Boolean myCreated;
|
||||||
|
|
||||||
|
@ -42,7 +44,7 @@ public class MethodOutcome {
|
||||||
* @param theId
|
* @param theId
|
||||||
* The ID of the created/updated resource
|
* The ID of the created/updated resource
|
||||||
*/
|
*/
|
||||||
public MethodOutcome(IdDt theId) {
|
public MethodOutcome(IIdType theId) {
|
||||||
myId = theId;
|
myId = theId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +72,7 @@ public class MethodOutcome {
|
||||||
* @param theBaseOperationOutcome
|
* @param theBaseOperationOutcome
|
||||||
* The operation outcome to return with the response (or null for none)
|
* The operation outcome to return with the response (or null for none)
|
||||||
*/
|
*/
|
||||||
public MethodOutcome(IdDt theId, BaseOperationOutcome theBaseOperationOutcome) {
|
public MethodOutcome(IdDt theId, IBaseOperationOutcome theBaseOperationOutcome) {
|
||||||
myId = theId;
|
myId = theId;
|
||||||
myOperationOutcome = theBaseOperationOutcome;
|
myOperationOutcome = theBaseOperationOutcome;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +90,7 @@ public class MethodOutcome {
|
||||||
* If not null, indicates whether the resource was created (as opposed to being updated). This is generally not needed, since the server can assume based on the method being called
|
* If not null, indicates whether the resource was created (as opposed to being updated). This is generally not needed, since the server can assume based on the method being called
|
||||||
* whether the result was a creation or an update. However, it can be useful if you are implementing an update method that does a create if the ID doesn't already exist.
|
* whether the result was a creation or an update. However, it can be useful if you are implementing an update method that does a create if the ID doesn't already exist.
|
||||||
*/
|
*/
|
||||||
public MethodOutcome(IdDt theId, BaseOperationOutcome theBaseOperationOutcome, Boolean theCreated) {
|
public MethodOutcome(IdDt theId, IBaseOperationOutcome theBaseOperationOutcome, Boolean theCreated) {
|
||||||
myId = theId;
|
myId = theId;
|
||||||
myOperationOutcome = theBaseOperationOutcome;
|
myOperationOutcome = theBaseOperationOutcome;
|
||||||
myCreated = theCreated;
|
myCreated = theCreated;
|
||||||
|
@ -107,22 +109,22 @@ public class MethodOutcome {
|
||||||
* @deprecated Use the constructor which accepts a single IdDt parameter, and include the logical ID and version ID in that IdDt instance
|
* @deprecated Use the constructor which accepts a single IdDt parameter, and include the logical ID and version ID in that IdDt instance
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public MethodOutcome(IdDt theId, IdDt theVersionId, BaseOperationOutcome theBaseOperationOutcome) {
|
public MethodOutcome(IdDt theId, IdDt theVersionId, IBaseOperationOutcome theBaseOperationOutcome) {
|
||||||
myId = theId;
|
myId = theId;
|
||||||
myVersionId = theVersionId;
|
myVersionId = theVersionId;
|
||||||
myOperationOutcome = theBaseOperationOutcome;
|
myOperationOutcome = theBaseOperationOutcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IdDt getId() {
|
public IIdType getId() {
|
||||||
return myId;
|
return myId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link BaseOperationOutcome} resource to return to the client or <code>null</code> if none.
|
* Returns the {@link IBaseOperationOutcome} resource to return to the client or <code>null</code> if none.
|
||||||
*
|
*
|
||||||
* @return This method <b>will return null</b>, unlike many methods in the API.
|
* @return This method <b>will return null</b>, unlike many methods in the API.
|
||||||
*/
|
*/
|
||||||
public BaseOperationOutcome getOperationOutcome() {
|
public IBaseOperationOutcome getOperationOutcome() {
|
||||||
return myOperationOutcome;
|
return myOperationOutcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,9 +169,9 @@ public class MethodOutcome {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link BaseOperationOutcome} resource to return to the client. Set to <code>null</code> (which is the default) if none.
|
* Sets the {@link IBaseOperationOutcome} resource to return to the client. Set to <code>null</code> (which is the default) if none.
|
||||||
*/
|
*/
|
||||||
public void setOperationOutcome(BaseOperationOutcome theBaseOperationOutcome) {
|
public void setOperationOutcome(IBaseOperationOutcome theBaseOperationOutcome) {
|
||||||
myOperationOutcome = theBaseOperationOutcome;
|
myOperationOutcome = theBaseOperationOutcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -216,9 +216,9 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
return delete(theType, new IdDt(theId));
|
return delete(theType, new IdDt(theId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends IBaseResource> T doReadOrVRead(final Class<T> theType, IdDt theId, boolean theVRead, ICallable<T> theNotModifiedHandler, String theIfVersionMatches) {
|
private <T extends IBaseResource> T doReadOrVRead(final Class<T> theType, IIdType theId, boolean theVRead, ICallable<T> theNotModifiedHandler, String theIfVersionMatches) {
|
||||||
String resName = toResourceName(theType);
|
String resName = toResourceName(theType);
|
||||||
IdDt id = theId;
|
IIdType id = theId;
|
||||||
if (!id.hasBaseUrl()) {
|
if (!id.hasBaseUrl()) {
|
||||||
id = new IdDt(resName, id.getIdPart(), id.getVersionIdPart());
|
id = new IdDt(resName, id.getIdPart(), id.getVersionIdPart());
|
||||||
}
|
}
|
||||||
|
@ -1289,7 +1289,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
private class ReadInternal extends BaseClientExecutable implements IRead, IReadTyped, IReadExecutable {
|
private class ReadInternal extends BaseClientExecutable implements IRead, IReadTyped, IReadExecutable {
|
||||||
private IdDt myId;
|
private IIdType myId;
|
||||||
private String myIfVersionMatches;
|
private String myIfVersionMatches;
|
||||||
private ICallable myNotModifiedHandler;
|
private ICallable myNotModifiedHandler;
|
||||||
private RuntimeResourceDefinition myType;
|
private RuntimeResourceDefinition myType;
|
||||||
|
@ -1370,7 +1370,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IReadExecutable withId(IdDt theId) {
|
public IReadExecutable withId(IIdType theId) {
|
||||||
Validate.notNull(theId, "The ID can not be null");
|
Validate.notNull(theId, "The ID can not be null");
|
||||||
Validate.notBlank(theId.getIdPart(), "The ID can not be blank");
|
Validate.notBlank(theId.getIdPart(), "The ID can not be blank");
|
||||||
myId = theId.toUnqualified();
|
myId = theId.toUnqualified();
|
||||||
|
@ -1392,7 +1392,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IReadExecutable withUrl(IdDt theUrl) {
|
public IReadExecutable withUrl(IIdType theUrl) {
|
||||||
Validate.notNull(theUrl, "theUrl can not be null");
|
Validate.notNull(theUrl, "theUrl can not be null");
|
||||||
myId = theUrl;
|
myId = theUrl;
|
||||||
processUrl();
|
processUrl();
|
||||||
|
@ -1434,10 +1434,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
|
|
||||||
private final class ResourceResponseHandler<T extends IBaseResource> implements IClientResponseHandler<T> {
|
private final class ResourceResponseHandler<T extends IBaseResource> implements IClientResponseHandler<T> {
|
||||||
|
|
||||||
private IdDt myId;
|
private IIdType myId;
|
||||||
private Class<T> myType;
|
private Class<T> myType;
|
||||||
|
|
||||||
public ResourceResponseHandler(Class<T> theType, IdDt theId) {
|
public ResourceResponseHandler(Class<T> theType, IIdType theId) {
|
||||||
myType = theType;
|
myType = theType;
|
||||||
myId = theId;
|
myId = theId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -382,5 +382,6 @@ public interface IGenericClient extends IRestfulClient {
|
||||||
*/
|
*/
|
||||||
<T extends IBaseResource> T vread(Class<T> theType, String theId, String theVersionId);
|
<T extends IBaseResource> T vread(Class<T> theType, String theId, String theVersionId);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,7 @@ package ca.uhn.fhir.rest.gclient;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
|
||||||
|
|
||||||
public interface IReadTyped<T extends IBaseResource> {
|
public interface IReadTyped<T extends IBaseResource> {
|
||||||
|
|
||||||
|
@ -34,11 +33,11 @@ public interface IReadTyped<T extends IBaseResource> {
|
||||||
* Search using an ID. Note that even if theId contains a base URL it will be
|
* Search using an ID. Note that even if theId contains a base URL it will be
|
||||||
* ignored in favour of the base url for the given client. If you want to specify
|
* ignored in favour of the base url for the given client. If you want to specify
|
||||||
* an absolute URL including a base and have that base used instead, use
|
* an absolute URL including a base and have that base used instead, use
|
||||||
* {@link #withUrl(IdDt)}
|
* {@link #withUrl(IIdType)}
|
||||||
*/
|
*/
|
||||||
IReadExecutable<T> withId(IdDt theId);
|
IReadExecutable<T> withId(IIdType theId);
|
||||||
|
|
||||||
IReadExecutable<T> withUrl(String theUrl);
|
IReadExecutable<T> withUrl(String theUrl);
|
||||||
|
|
||||||
IReadExecutable<T> withUrl(IdDt theUrl);
|
IReadExecutable<T> withUrl(IIdType theUrl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
|
@ -362,8 +363,8 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
|
||||||
return BundleProviders.newEmptyList();
|
return BundleProviders.newEmptyList();
|
||||||
} else if (response instanceof IBundleProvider) {
|
} else if (response instanceof IBundleProvider) {
|
||||||
return (IBundleProvider) response;
|
return (IBundleProvider) response;
|
||||||
} else if (response instanceof IResource) {
|
} else if (response instanceof IBaseResource) {
|
||||||
return BundleProviders.newList((IResource) response);
|
return BundleProviders.newList((IBaseResource) response);
|
||||||
} else if (response instanceof Collection) {
|
} else if (response instanceof Collection) {
|
||||||
List<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
List<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||||
for (Object next : ((Collection<?>) response)) {
|
for (Object next : ((Collection<?>) response)) {
|
||||||
|
@ -427,18 +428,18 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
|
||||||
// returns a bundle
|
// returns a bundle
|
||||||
} else if (Collection.class.isAssignableFrom(returnTypeFromMethod)) {
|
} else if (Collection.class.isAssignableFrom(returnTypeFromMethod)) {
|
||||||
returnTypeFromMethod = ReflectionUtil.getGenericCollectionTypeOfMethodReturnType(theMethod);
|
returnTypeFromMethod = ReflectionUtil.getGenericCollectionTypeOfMethodReturnType(theMethod);
|
||||||
if (!verifyIsValidResourceReturnType(returnTypeFromMethod) && !IResource.class.equals(returnTypeFromMethod)) {
|
if (!verifyIsValidResourceReturnType(returnTypeFromMethod) && !isResourceInterface(returnTypeFromMethod)) {
|
||||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returns a collection with generic type " + toLogString(returnTypeFromMethod)
|
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returns a collection with generic type " + toLogString(returnTypeFromMethod)
|
||||||
+ " - Must return a resource type or a collection (List, Set) with a resource type parameter (e.g. List<Patient> or List<IResource> )");
|
+ " - Must return a resource type or a collection (List, Set) with a resource type parameter (e.g. List<Patient> or List<IBaseResource> )");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!IResource.class.equals(returnTypeFromMethod) && !verifyIsValidResourceReturnType(returnTypeFromMethod)) {
|
if (!isResourceInterface(returnTypeFromMethod) && !verifyIsValidResourceReturnType(returnTypeFromMethod)) {
|
||||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returns " + toLogString(returnTypeFromMethod) + " - Must return a resource type (eg Patient, "
|
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returns " + toLogString(returnTypeFromMethod) + " - Must return a resource type (eg Patient, "
|
||||||
+ Bundle.class.getSimpleName() + ", " + IBundleProvider.class.getSimpleName() + ", etc., see the documentation for more details)");
|
+ Bundle.class.getSimpleName() + ", " + IBundleProvider.class.getSimpleName() + ", etc., see the documentation for more details)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Class<? extends IResource> returnTypeFromAnnotation = IResource.class;
|
Class<? extends IBaseResource> returnTypeFromAnnotation = IBaseResource.class;
|
||||||
if (read != null) {
|
if (read != null) {
|
||||||
returnTypeFromAnnotation = read.type();
|
returnTypeFromAnnotation = read.type();
|
||||||
} else if (search != null) {
|
} else if (search != null) {
|
||||||
|
@ -462,7 +463,7 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
if (returnTypeFromRp != null) {
|
if (returnTypeFromRp != null) {
|
||||||
if (returnTypeFromAnnotation != null && returnTypeFromAnnotation != IResource.class) {
|
if (returnTypeFromAnnotation != null && !isResourceInterface(returnTypeFromAnnotation)) {
|
||||||
if (!returnTypeFromRp.isAssignableFrom(returnTypeFromAnnotation)) {
|
if (!returnTypeFromRp.isAssignableFrom(returnTypeFromAnnotation)) {
|
||||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " returns type " + returnTypeFromMethod.getCanonicalName() + " - Must return " + returnTypeFromRp.getCanonicalName()
|
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " returns type " + returnTypeFromMethod.getCanonicalName() + " - Must return " + returnTypeFromRp.getCanonicalName()
|
||||||
+ " (or a subclass of it) per IResourceProvider contract");
|
+ " (or a subclass of it) per IResourceProvider contract");
|
||||||
|
@ -476,7 +477,7 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
|
||||||
returnType = returnTypeFromRp;
|
returnType = returnTypeFromRp;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (returnTypeFromAnnotation != IResource.class) {
|
if (!isResourceInterface(returnTypeFromAnnotation)) {
|
||||||
if (!verifyIsValidResourceReturnType(returnTypeFromAnnotation)) {
|
if (!verifyIsValidResourceReturnType(returnTypeFromAnnotation)) {
|
||||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returns " + toLogString(returnTypeFromAnnotation)
|
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returns " + toLogString(returnTypeFromAnnotation)
|
||||||
+ " according to annotation - Must return a resource type");
|
+ " according to annotation - Must return a resource type");
|
||||||
|
@ -486,7 +487,7 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
|
||||||
// if (IRestfulClient.class.isAssignableFrom(theMethod.getDeclaringClass())) {
|
// if (IRestfulClient.class.isAssignableFrom(theMethod.getDeclaringClass())) {
|
||||||
// Clients don't define their methods in resource specific types, so they can
|
// Clients don't define their methods in resource specific types, so they can
|
||||||
// infer their resource type from the method return type.
|
// infer their resource type from the method return type.
|
||||||
returnType = (Class<? extends IResource>) returnTypeFromMethod;
|
returnType = (Class<? extends IBaseResource>) returnTypeFromMethod;
|
||||||
// } else {
|
// } else {
|
||||||
// This is a plain provider method returning a resource, so it should be
|
// This is a plain provider method returning a resource, so it should be
|
||||||
// an operation or global search presumably
|
// an operation or global search presumably
|
||||||
|
@ -555,6 +556,10 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
|
||||||
// return sm;
|
// return sm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isResourceInterface(Class<?> theReturnTypeFromMethod) {
|
||||||
|
return theReturnTypeFromMethod.equals(IBaseResource.class) || theReturnTypeFromMethod.equals(IResource.class) || theReturnTypeFromMethod.equals(IAnyResource.class);
|
||||||
|
}
|
||||||
|
|
||||||
private static void populateException(BaseServerResponseException theEx, Reader theResponseReader) {
|
private static void populateException(BaseServerResponseException theEx, Reader theResponseReader) {
|
||||||
try {
|
try {
|
||||||
String responseText = IOUtils.toString(theResponseReader);
|
String responseText = IOUtils.toString(theResponseReader);
|
||||||
|
|
|
@ -31,11 +31,11 @@ import java.util.Set;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
|
@ -170,7 +170,7 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseOperationOutcome outcome = response != null ? response.getOperationOutcome() : null;
|
IBaseOperationOutcome outcome = response != null ? response.getOperationOutcome() : null;
|
||||||
for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) {
|
for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) {
|
||||||
IServerInterceptor next = theServer.getInterceptors().get(i);
|
IServerInterceptor next = theServer.getInterceptors().get(i);
|
||||||
boolean continueProcessing = next.outgoingResponse(theRequest, outcome, theRequest.getServletRequest(), theRequest.getServletResponse());
|
boolean continueProcessing = next.outgoingResponse(theRequest, outcome, theRequest.getServletRequest(), theRequest.getServletResponse());
|
||||||
|
|
|
@ -24,10 +24,12 @@ import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||||
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
||||||
import ca.uhn.fhir.rest.param.ResourceParameter;
|
import ca.uhn.fhir.rest.param.ResourceParameter;
|
||||||
|
@ -39,7 +41,9 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
|
||||||
private String myResourceName;
|
private String myResourceName;
|
||||||
private int myResourceParameterIndex;
|
private int myResourceParameterIndex;
|
||||||
private Class<? extends IBaseResource> myResourceType;
|
private Class<? extends IBaseResource> myResourceType;
|
||||||
|
private Class<? extends IIdType> myIdParamType;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public BaseOutcomeReturningMethodBindingWithResourceParam(Method theMethod, FhirContext theContext, Class<?> theMethodAnnotation, Object theProvider) {
|
public BaseOutcomeReturningMethodBindingWithResourceParam(Method theMethod, FhirContext theContext, Class<?> theMethodAnnotation, Object theProvider) {
|
||||||
super(theMethod, theContext, theMethodAnnotation, theProvider);
|
super(theMethod, theContext, theMethodAnnotation, theProvider);
|
||||||
|
|
||||||
|
@ -72,7 +76,10 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
|
||||||
|
|
||||||
myResourceName = theContext.getResourceDefinition(myResourceType).getName();
|
myResourceName = theContext.getResourceDefinition(myResourceType).getName();
|
||||||
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod);
|
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod);
|
||||||
|
if (myIdParamIndex != null) {
|
||||||
|
myIdParamType = (Class<? extends IIdType>) theMethod.getParameterTypes()[myIdParamIndex];
|
||||||
|
}
|
||||||
|
|
||||||
if (resourceParameter == null) {
|
if (resourceParameter == null) {
|
||||||
throw new ConfigurationException("Method " + theMethod.getName() + " in type " + theMethod.getDeclaringClass().getCanonicalName() + " does not have a resource parameter annotated with @" + ResourceParam.class.getSimpleName());
|
throw new ConfigurationException("Method " + theMethod.getName() + " in type " + theMethod.getDeclaringClass().getCanonicalName() + " does not have a resource parameter annotated with @" + ResourceParam.class.getSimpleName());
|
||||||
}
|
}
|
||||||
|
@ -82,10 +89,11 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
|
||||||
@Override
|
@Override
|
||||||
protected void addParametersForServerRequest(RequestDetails theRequest, Object[] theParams) {
|
protected void addParametersForServerRequest(RequestDetails theRequest, Object[] theParams) {
|
||||||
if (myIdParamIndex != null) {
|
if (myIdParamIndex != null) {
|
||||||
theParams[myIdParamIndex] = theRequest.getId();
|
theParams[myIdParamIndex] = MethodUtil.convertIdToType(theRequest.getId(), myIdParamType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getResourceName() {
|
public String getResourceName() {
|
||||||
return myResourceName;
|
return myResourceName;
|
||||||
|
|
|
@ -29,6 +29,7 @@ import java.lang.reflect.Modifier;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -38,6 +39,7 @@ import java.util.Set;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
@ -124,17 +126,12 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theReturnResourceType != null) {
|
if (theReturnResourceType != null) {
|
||||||
if (IResource.class.isAssignableFrom(theReturnResourceType)) {
|
if (IBaseResource.class.isAssignableFrom(theReturnResourceType)) {
|
||||||
ResourceDef resourceDefAnnotation = theReturnResourceType.getAnnotation(ResourceDef.class);
|
if (Modifier.isAbstract(theReturnResourceType.getModifiers()) || Modifier.isInterface(theReturnResourceType.getModifiers())) {
|
||||||
if (resourceDefAnnotation == null) {
|
// If we're returning an abstract type, that's ok
|
||||||
if (Modifier.isAbstract(theReturnResourceType.getModifiers())) {
|
|
||||||
// If we're returning an abstract type, that's ok
|
|
||||||
} else {
|
|
||||||
throw new ConfigurationException(theReturnResourceType.getCanonicalName() + " has no @" + ResourceDef.class.getSimpleName() + " annotation");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
myResourceType = (Class<? extends IResource>) theReturnResourceType;
|
myResourceType = (Class<? extends IResource>) theReturnResourceType;
|
||||||
myResourceName = resourceDefAnnotation.name();
|
myResourceName = theContext.getResourceDefinition(myResourceType).getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,14 +306,14 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
||||||
|
|
||||||
if (getMethodReturnType() == MethodReturnTypeEnum.BUNDLE_RESOURCE) {
|
if (getMethodReturnType() == MethodReturnTypeEnum.BUNDLE_RESOURCE) {
|
||||||
IBaseResource resource;
|
IBaseResource resource;
|
||||||
InstantDt lastUpdated;
|
IPrimitiveType<Date> lastUpdated;
|
||||||
if (resultObj instanceof IBundleProvider) {
|
if (resultObj instanceof IBundleProvider) {
|
||||||
IBundleProvider result = (IBundleProvider) resultObj;
|
IBundleProvider result = (IBundleProvider) resultObj;
|
||||||
resource = result.getResources(0, 1).get(0);
|
resource = result.getResources(0, 1).get(0);
|
||||||
lastUpdated = result.getPublished();
|
lastUpdated = result.getPublished();
|
||||||
} else {
|
} else {
|
||||||
resource = (IResource) resultObj;
|
resource = (IBaseResource) resultObj;
|
||||||
lastUpdated = ResourceMetadataKeyEnum.UPDATED.get((IResource) resource);
|
lastUpdated = theServer.getFhirContext().getVersion().getLastUpdated(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -22,10 +22,11 @@ package ca.uhn.fhir.rest.method;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseConformance;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
|
||||||
import ca.uhn.fhir.model.base.resource.BaseConformance;
|
|
||||||
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
|
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
|
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
|
||||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||||
|
@ -43,7 +44,9 @@ public class ConformanceMethodBinding extends BaseResourceReturningMethodBinding
|
||||||
// if (Modifier.isAbstract(theMethod.getReturnType().getModifiers())) {
|
// if (Modifier.isAbstract(theMethod.getReturnType().getModifiers())) {
|
||||||
// throw new ConfigurationException("Conformance resource provider method '" + theMethod.getName() + "' must not be abstract");
|
// throw new ConfigurationException("Conformance resource provider method '" + theMethod.getName() + "' must not be abstract");
|
||||||
// }
|
// }
|
||||||
if (getMethodReturnType() != MethodReturnTypeEnum.RESOURCE || !BaseConformance.class.isAssignableFrom((Class<?>) theMethod.getGenericReturnType())) {
|
MethodReturnTypeEnum methodReturnType = getMethodReturnType();
|
||||||
|
Class<?> genericReturnType = (Class<?>) theMethod.getGenericReturnType();
|
||||||
|
if (methodReturnType != MethodReturnTypeEnum.RESOURCE || !IBaseConformance.class.isAssignableFrom(genericReturnType)) {
|
||||||
throw new ConfigurationException("Conformance resource provider method '" + theMethod.getName() + "' should return a Conformance resource class, returns: " + theMethod.getReturnType());
|
throw new ConfigurationException("Conformance resource provider method '" + theMethod.getName() + "' should return a Conformance resource class, returns: " + theMethod.getReturnType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +73,7 @@ public class ConformanceMethodBinding extends BaseResourceReturningMethodBinding
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBundleProvider invokeServer(RequestDetails theRequest, Object[] theMethodParams) throws BaseServerResponseException {
|
public IBundleProvider invokeServer(RequestDetails theRequest, Object[] theMethodParams) throws BaseServerResponseException {
|
||||||
IResource conf = (IResource) invokeServerMethod(theMethodParams);
|
IBaseResource conf = (IBaseResource) invokeServerMethod(theMethodParams);
|
||||||
return new SimpleBundleProvider(conf);
|
return new SimpleBundleProvider(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ public class DynamicSearchMethodBinding extends BaseResourceReturningMethodBindi
|
||||||
@Override
|
@Override
|
||||||
public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) {
|
public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) {
|
||||||
if (!theRequest.getResourceName().equals(getResourceName())) {
|
if (!theRequest.getResourceName().equals(getResourceName())) {
|
||||||
ourLog.trace("Method {} doesn't match because resource name {} != {}", getMethod().getName(), theRequest.getResourceName(), getResourceName());
|
ourLog.trace("Method {} doesn't match because resource name {} != {}", new Object[] { getMethod().getName(), theRequest.getResourceName(), getResourceName() } );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (theRequest.getId() != null && myIdParamIndex == null) {
|
if (theRequest.getId() != null && myIdParamIndex == null) {
|
||||||
|
|
|
@ -127,6 +127,22 @@ public class MethodUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static IIdType convertIdToType(IIdType value, Class<? extends IIdType> idParamType) {
|
||||||
|
if (value != null && !idParamType.isAssignableFrom(value.getClass())) {
|
||||||
|
try {
|
||||||
|
IIdType newValue = idParamType.newInstance();
|
||||||
|
newValue.setValue(value.getValue());
|
||||||
|
value = newValue;
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
throw new ConfigurationException("Failed to instantiate " + idParamType, e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new ConfigurationException("Failed to instantiate " + idParamType, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
public static HttpGetClientInvocation createConformanceInvocation() {
|
public static HttpGetClientInvocation createConformanceInvocation() {
|
||||||
return new HttpGetClientInvocation("metadata");
|
return new HttpGetClientInvocation("metadata");
|
||||||
}
|
}
|
||||||
|
@ -181,42 +197,6 @@ public class MethodUtil {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HttpPutClientInvocation createUpdateInvocation(IBaseResource theResource, String theResourceBody, IIdType theId, FhirContext theContext) {
|
|
||||||
String resourceName = theContext.getResourceDefinition(theResource).getName();
|
|
||||||
StringBuilder urlBuilder = new StringBuilder();
|
|
||||||
urlBuilder.append(resourceName);
|
|
||||||
urlBuilder.append('/');
|
|
||||||
urlBuilder.append(theId.getIdPart());
|
|
||||||
String urlExtension = urlBuilder.toString();
|
|
||||||
|
|
||||||
HttpPutClientInvocation retVal;
|
|
||||||
if (StringUtils.isBlank(theResourceBody)) {
|
|
||||||
retVal = new HttpPutClientInvocation(theContext, theResource, urlExtension);
|
|
||||||
} else {
|
|
||||||
retVal = new HttpPutClientInvocation(theContext, theResourceBody, false, urlExtension);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (theId.hasVersionIdPart()) {
|
|
||||||
if (theContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
|
||||||
retVal.addHeader(Constants.HEADER_IF_MATCH, '"' + theId.getVersionIdPart() + '"');
|
|
||||||
} else {
|
|
||||||
String versionId = theId.getVersionIdPart();
|
|
||||||
if (StringUtils.isNotBlank(versionId)) {
|
|
||||||
urlBuilder.append('/');
|
|
||||||
urlBuilder.append(Constants.PARAM_HISTORY);
|
|
||||||
urlBuilder.append('/');
|
|
||||||
urlBuilder.append(versionId);
|
|
||||||
retVal.addHeader(Constants.HEADER_CONTENT_LOCATION, urlBuilder.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addTagsToPostOrPut(theContext, theResource, retVal);
|
|
||||||
// addContentTypeHeaderBasedOnDetectedType(retVal, theResourceBody);
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HttpPutClientInvocation createUpdateInvocation(FhirContext theContext, IBaseResource theResource, String theResourceBody, Map<String, List<String>> theMatchParams) {
|
public static HttpPutClientInvocation createUpdateInvocation(FhirContext theContext, IBaseResource theResource, String theResourceBody, Map<String, List<String>> theMatchParams) {
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
|
|
||||||
|
@ -263,6 +243,42 @@ public class MethodUtil {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static HttpPutClientInvocation createUpdateInvocation(IBaseResource theResource, String theResourceBody, IIdType theId, FhirContext theContext) {
|
||||||
|
String resourceName = theContext.getResourceDefinition(theResource).getName();
|
||||||
|
StringBuilder urlBuilder = new StringBuilder();
|
||||||
|
urlBuilder.append(resourceName);
|
||||||
|
urlBuilder.append('/');
|
||||||
|
urlBuilder.append(theId.getIdPart());
|
||||||
|
String urlExtension = urlBuilder.toString();
|
||||||
|
|
||||||
|
HttpPutClientInvocation retVal;
|
||||||
|
if (StringUtils.isBlank(theResourceBody)) {
|
||||||
|
retVal = new HttpPutClientInvocation(theContext, theResource, urlExtension);
|
||||||
|
} else {
|
||||||
|
retVal = new HttpPutClientInvocation(theContext, theResourceBody, false, urlExtension);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theId.hasVersionIdPart()) {
|
||||||
|
if (theContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
|
||||||
|
retVal.addHeader(Constants.HEADER_IF_MATCH, '"' + theId.getVersionIdPart() + '"');
|
||||||
|
} else {
|
||||||
|
String versionId = theId.getVersionIdPart();
|
||||||
|
if (StringUtils.isNotBlank(versionId)) {
|
||||||
|
urlBuilder.append('/');
|
||||||
|
urlBuilder.append(Constants.PARAM_HISTORY);
|
||||||
|
urlBuilder.append('/');
|
||||||
|
urlBuilder.append(versionId);
|
||||||
|
retVal.addHeader(Constants.HEADER_CONTENT_LOCATION, urlBuilder.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addTagsToPostOrPut(theContext, theResource, retVal);
|
||||||
|
// addContentTypeHeaderBasedOnDetectedType(retVal, theResourceBody);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
public static EncodingEnum detectEncoding(String theBody) {
|
public static EncodingEnum detectEncoding(String theBody) {
|
||||||
EncodingEnum retVal = detectEncodingNoDefault(theBody);
|
EncodingEnum retVal = detectEncodingNoDefault(theBody);
|
||||||
if (retVal == null) {
|
if (retVal == null) {
|
||||||
|
@ -299,6 +315,10 @@ public class MethodUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Integer findConditionalOperationParameterIndex(Method theMethod) {
|
||||||
|
return MethodUtil.findParamAnnotationIndex(theMethod, ConditionalUrlParam.class);
|
||||||
|
}
|
||||||
|
|
||||||
public static Integer findIdParameterIndex(Method theMethod) {
|
public static Integer findIdParameterIndex(Method theMethod) {
|
||||||
return MethodUtil.findParamAnnotationIndex(theMethod, IdParam.class);
|
return MethodUtil.findParamAnnotationIndex(theMethod, IdParam.class);
|
||||||
}
|
}
|
||||||
|
@ -322,10 +342,6 @@ public class MethodUtil {
|
||||||
return MethodUtil.findParamAnnotationIndex(theMethod, TagListParam.class);
|
return MethodUtil.findParamAnnotationIndex(theMethod, TagListParam.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Integer findConditionalOperationParameterIndex(Method theMethod) {
|
|
||||||
return MethodUtil.findParamAnnotationIndex(theMethod, ConditionalUrlParam.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public static Integer findVersionIdParameterIndex(Method theMethod) {
|
public static Integer findVersionIdParameterIndex(Method theMethod) {
|
||||||
return MethodUtil.findParamAnnotationIndex(theMethod, VersionIdParam.class);
|
return MethodUtil.findParamAnnotationIndex(theMethod, VersionIdParam.class);
|
||||||
|
@ -447,13 +463,13 @@ public class MethodUtil {
|
||||||
}
|
}
|
||||||
param = new OperationParameter(Constants.EXTOP_VALIDATE, Constants.EXTOP_VALIDATE_MODE, 0, 1).setConverter(new IConverter() {
|
param = new OperationParameter(Constants.EXTOP_VALIDATE, Constants.EXTOP_VALIDATE_MODE, 0, 1).setConverter(new IConverter() {
|
||||||
@Override
|
@Override
|
||||||
public Object outgoingClient(Object theObject) {
|
public Object incomingServer(Object theObject) {
|
||||||
return new StringDt(((ValidationModeEnum)theObject).name().toLowerCase());
|
return ValidationModeEnum.valueOf(theObject.toString().toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object incomingServer(Object theObject) {
|
public Object outgoingClient(Object theObject) {
|
||||||
return ValidationModeEnum.valueOf(theObject.toString().toUpperCase());
|
return new StringDt(((ValidationModeEnum)theObject).name().toLowerCase());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (nextAnnotation instanceof Validate.Profile) {
|
} else if (nextAnnotation instanceof Validate.Profile) {
|
||||||
|
@ -462,13 +478,13 @@ public class MethodUtil {
|
||||||
}
|
}
|
||||||
param = new OperationParameter(Constants.EXTOP_VALIDATE, Constants.EXTOP_VALIDATE_PROFILE, 0, 1).setConverter(new IConverter() {
|
param = new OperationParameter(Constants.EXTOP_VALIDATE, Constants.EXTOP_VALIDATE_PROFILE, 0, 1).setConverter(new IConverter() {
|
||||||
@Override
|
@Override
|
||||||
public Object outgoingClient(Object theObject) {
|
public Object incomingServer(Object theObject) {
|
||||||
return new StringDt(theObject.toString());
|
return theObject.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object incomingServer(Object theObject) {
|
public Object outgoingClient(Object theObject) {
|
||||||
return theObject.toString();
|
return new StringDt(theObject.toString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -492,7 +508,7 @@ public class MethodUtil {
|
||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void parseClientRequestResourceHeaders(IdDt theRequestedId, Map<String, List<String>> theHeaders, IBaseResource resource) {
|
public static void parseClientRequestResourceHeaders(IIdType theRequestedId, Map<String, List<String>> theHeaders, IBaseResource resource) {
|
||||||
List<String> lmHeaders = theHeaders.get(Constants.HEADER_LAST_MODIFIED_LOWERCASE);
|
List<String> lmHeaders = theHeaders.get(Constants.HEADER_LAST_MODIFIED_LOWERCASE);
|
||||||
if (lmHeaders != null && lmHeaders.size() > 0 && StringUtils.isNotBlank(lmHeaders.get(0))) {
|
if (lmHeaders != null && lmHeaders.size() > 0 && StringUtils.isNotBlank(lmHeaders.get(0))) {
|
||||||
String headerValue = lmHeaders.get(0);
|
String headerValue = lmHeaders.get(0);
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseBinary;
|
import org.hl7.fhir.instance.model.api.IBaseBinary;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
@ -60,7 +61,9 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
|
||||||
private Integer myIdIndex;
|
private Integer myIdIndex;
|
||||||
private boolean mySupportsVersion;
|
private boolean mySupportsVersion;
|
||||||
private Integer myVersionIdIndex;
|
private Integer myVersionIdIndex;
|
||||||
|
private Class<? extends IIdType> myIdParameterType;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public ReadMethodBinding(Class<? extends IBaseResource> theAnnotatedResourceType, Method theMethod, FhirContext theContext, Object theProvider) {
|
public ReadMethodBinding(Class<? extends IBaseResource> theAnnotatedResourceType, Method theMethod, FhirContext theContext, Object theProvider) {
|
||||||
super(theAnnotatedResourceType, theMethod, theContext, theProvider);
|
super(theAnnotatedResourceType, theMethod, theContext, theProvider);
|
||||||
|
|
||||||
|
@ -69,17 +72,19 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
|
||||||
Integer idIndex = MethodUtil.findIdParameterIndex(theMethod);
|
Integer idIndex = MethodUtil.findIdParameterIndex(theMethod);
|
||||||
Integer versionIdIndex = MethodUtil.findVersionIdParameterIndex(theMethod);
|
Integer versionIdIndex = MethodUtil.findVersionIdParameterIndex(theMethod);
|
||||||
|
|
||||||
|
Class<?>[] parameterTypes = theMethod.getParameterTypes();
|
||||||
|
|
||||||
mySupportsVersion = theMethod.getAnnotation(Read.class).version();
|
mySupportsVersion = theMethod.getAnnotation(Read.class).version();
|
||||||
myIdIndex = idIndex;
|
myIdIndex = idIndex;
|
||||||
myVersionIdIndex = versionIdIndex;
|
myVersionIdIndex = versionIdIndex;
|
||||||
|
|
||||||
if (myIdIndex== null) {
|
if (myIdIndex == null) {
|
||||||
throw new ConfigurationException("@" + Read.class.getSimpleName() + " method " + theMethod.getName() + " on type \"" + theMethod.getDeclaringClass().getName() + "\" does not have a parameter annotated with @" + IdParam.class.getSimpleName());
|
throw new ConfigurationException("@" + Read.class.getSimpleName() + " method " + theMethod.getName() + " on type \"" + theMethod.getDeclaringClass().getName() + "\" does not have a parameter annotated with @" + IdParam.class.getSimpleName());
|
||||||
}
|
}
|
||||||
|
myIdParameterType = (Class<? extends IIdType>) parameterTypes[myIdIndex];
|
||||||
Class<?>[] parameterTypes = theMethod.getParameterTypes();
|
|
||||||
if (!IdDt.class.equals(parameterTypes[myIdIndex])) {
|
if (!IIdType.class.isAssignableFrom(myIdParameterType)) {
|
||||||
throw new ConfigurationException("ID parameter must be of type: " + IdDt.class.getCanonicalName() + " - Found: " + parameterTypes[myIdIndex]);
|
throw new ConfigurationException("ID parameter must be of type IdDt or IdType - Found: " + myIdParameterType);
|
||||||
}
|
}
|
||||||
if (myVersionIdIndex != null && !IdDt.class.equals(parameterTypes[myVersionIdIndex])) {
|
if (myVersionIdIndex != null && !IdDt.class.equals(parameterTypes[myVersionIdIndex])) {
|
||||||
throw new ConfigurationException("Version ID parameter must be of type: " + IdDt.class.getCanonicalName() + " - Found: " + parameterTypes[myVersionIdIndex]);
|
throw new ConfigurationException("Version ID parameter must be of type: " + IdDt.class.getCanonicalName() + " - Found: " + parameterTypes[myVersionIdIndex]);
|
||||||
|
@ -173,7 +178,7 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
|
||||||
@Override
|
@Override
|
||||||
public Object invokeClient(String theResponseMimeType, InputStream theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
public Object invokeClient(String theResponseMimeType, InputStream theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
||||||
byte[] contents = IOUtils.toByteArray(theResponseReader);
|
byte[] contents = IOUtils.toByteArray(theResponseReader);
|
||||||
|
|
||||||
IBaseBinary resource = (IBaseBinary) getContext().getResourceDefinition("Binary").newInstance();
|
IBaseBinary resource = (IBaseBinary) getContext().getResourceDefinition("Binary").newInstance();
|
||||||
resource.setContentType(theResponseMimeType);
|
resource.setContentType(theResponseMimeType);
|
||||||
resource.setContent(contents);
|
resource.setContent(contents);
|
||||||
|
@ -194,7 +199,7 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBundleProvider invokeServer(RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException {
|
public IBundleProvider invokeServer(RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException {
|
||||||
theMethodParams[myIdIndex] = theRequest.getId();
|
theMethodParams[myIdIndex] = MethodUtil.convertIdToType(theRequest.getId(), myIdParameterType);
|
||||||
if (myVersionIdIndex != null) {
|
if (myVersionIdIndex != null) {
|
||||||
theMethodParams[myVersionIdIndex] = new IdDt(theRequest.getId().getVersionIdPart());
|
theMethodParams[myVersionIdIndex] = new IdDt(theRequest.getId().getVersionIdPart());
|
||||||
}
|
}
|
||||||
|
@ -207,7 +212,7 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
|
||||||
if (retVal.size() == 1 && StringUtils.isNotBlank(ifNoneMatch)) {
|
if (retVal.size() == 1 && StringUtils.isNotBlank(ifNoneMatch)) {
|
||||||
List<IBaseResource> responseResources = retVal.getResources(0, 1);
|
List<IBaseResource> responseResources = retVal.getResources(0, 1);
|
||||||
IBaseResource responseResource = responseResources.get(0);
|
IBaseResource responseResource = responseResources.get(0);
|
||||||
|
|
||||||
ifNoneMatch = MethodUtil.parseETagValue(ifNoneMatch);
|
ifNoneMatch = MethodUtil.parseETagValue(ifNoneMatch);
|
||||||
if (responseResource.getIdElement() != null && responseResource.getIdElement().hasVersionIdPart()) {
|
if (responseResource.getIdElement() != null && responseResource.getIdElement().hasVersionIdPart()) {
|
||||||
if (responseResource.getIdElement().getVersionIdPart().equals(ifNoneMatch)) {
|
if (responseResource.getIdElement().getVersionIdPart().equals(ifNoneMatch)) {
|
||||||
|
@ -230,19 +235,19 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
|
||||||
return mySupportsVersion || myVersionIdIndex != null;
|
return mySupportsVersion || myVersionIdIndex != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HttpGetClientInvocation createAbsoluteReadInvocation(IdDt theId) {
|
public static HttpGetClientInvocation createAbsoluteReadInvocation(IIdType theId) {
|
||||||
return new HttpGetClientInvocation(theId.toVersionless().getValue());
|
return new HttpGetClientInvocation(theId.toVersionless().getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HttpGetClientInvocation createAbsoluteVReadInvocation(IdDt theId) {
|
public static HttpGetClientInvocation createAbsoluteVReadInvocation(IIdType theId) {
|
||||||
return new HttpGetClientInvocation(theId.getValue());
|
return new HttpGetClientInvocation(theId.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HttpGetClientInvocation createReadInvocation(IdDt theId, String theResourceName) {
|
public static HttpGetClientInvocation createReadInvocation(IIdType theId, String theResourceName) {
|
||||||
return new HttpGetClientInvocation(new IdDt(theResourceName, theId.getIdPart()).getValue());
|
return new HttpGetClientInvocation(new IdDt(theResourceName, theId.getIdPart()).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HttpGetClientInvocation createVReadInvocation(IdDt theId, String theResourceName) {
|
public static HttpGetClientInvocation createVReadInvocation(IIdType theId, String theResourceName) {
|
||||||
return new HttpGetClientInvocation(new IdDt(theResourceName, theId.getIdPart(), theId.getVersionIdPart()).getValue());
|
return new HttpGetClientInvocation(new IdDt(theResourceName, theId.getIdPart(), theId.getVersionIdPart()).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,7 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
@Override
|
@Override
|
||||||
public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) {
|
public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) {
|
||||||
if (!theRequest.getResourceName().equals(getResourceName())) {
|
if (!theRequest.getResourceName().equals(getResourceName())) {
|
||||||
ourLog.trace("Method {} doesn't match because resource name {} != {}", getMethod().getName(), theRequest.getResourceName(), getResourceName());
|
ourLog.trace("Method {} doesn't match because resource name {} != {}", new Object[] { getMethod().getName(), theRequest.getResourceName(), getResourceName() } );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (theRequest.getId() != null && myIdParamIndex == null) {
|
if (theRequest.getId() != null && myIdParamIndex == null) {
|
||||||
|
|
|
@ -144,7 +144,7 @@ public abstract class BaseQueryParameter implements IParameter {
|
||||||
|
|
||||||
if (paramList.isEmpty()) {
|
if (paramList.isEmpty()) {
|
||||||
|
|
||||||
ourLog.debug("No value for parameter '{}' - Qualified names {} and qualifier whitelist {}", getName(), qualified, getQualifierWhitelist());
|
ourLog.debug("No value for parameter '{}' - Qualified names {} and qualifier whitelist {}", new Object[] { getName(), qualified, getQualifierWhitelist() } );
|
||||||
|
|
||||||
if (handlesMissing()) {
|
if (handlesMissing()) {
|
||||||
return parse(theRequest.getServer().getFhirContext(), paramList);
|
return parse(theRequest.getServer().getFhirContext(), paramList);
|
||||||
|
|
|
@ -20,9 +20,10 @@ package ca.uhn.fhir.rest.server;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -32,6 +33,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
|
@ -44,7 +46,6 @@ import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
|
||||||
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
|
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
|
||||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
@ -224,7 +225,7 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, InstantDt theLastUpdated) {
|
public void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, IPrimitiveType<Date> theLastUpdated) {
|
||||||
if (myBundle.getAuthorName().isEmpty()) {
|
if (myBundle.getAuthorName().isEmpty()) {
|
||||||
myBundle.getAuthorName().setValue(theAuthor);
|
myBundle.getAuthorName().setValue(theAuthor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,14 +20,15 @@ package ca.uhn.fhir.rest.server;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.api.Include;
|
import ca.uhn.fhir.model.api.Include;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
|
||||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,7 +39,7 @@ public interface IVersionSpecificBundleFactory {
|
||||||
|
|
||||||
void addResourcesToBundle(List<IBaseResource> theResult, BundleTypeEnum theBundleType, String theServerBase, BundleInclusionRule theBundleInclusionRule, Set<Include> theIncludes);
|
void addResourcesToBundle(List<IBaseResource> theResult, BundleTypeEnum theBundleType, String theServerBase, BundleInclusionRule theBundleInclusionRule, Set<Include> theIncludes);
|
||||||
|
|
||||||
void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, InstantDt theLastUpdated);
|
void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, IPrimitiveType<Date> theLastUpdated);
|
||||||
|
|
||||||
void initializeBundleFromBundleProvider(RestfulServer theServer, IBundleProvider theResult, EncodingEnum theResponseEncoding, String theServerBase, String theCompleteUrl, boolean thePrettyPrint,
|
void initializeBundleFromBundleProvider(RestfulServer theServer, IBundleProvider theResult, EncodingEnum theResponseEncoding, String theServerBase, String theCompleteUrl, boolean thePrettyPrint,
|
||||||
int theOffset, Integer theCount, String theSearchId, BundleTypeEnum theBundleType, Set<Include> theIncludes);
|
int theOffset, Integer theCount, String theSearchId, BundleTypeEnum theBundleType, Set<Include> theIncludes);
|
||||||
|
|
|
@ -31,10 +31,10 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
|
|
||||||
import ca.uhn.fhir.rest.method.RequestDetails;
|
import ca.uhn.fhir.rest.method.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
|
@ -42,28 +42,16 @@ import ca.uhn.fhir.rest.server.RestfulServer.NarrativeModeEnum;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
||||||
|
|
||||||
public class ExceptionHandlingInterceptor extends InterceptorAdapter {
|
public class ExceptionHandlingInterceptor extends InterceptorAdapter {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExceptionHandlingInterceptor.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExceptionHandlingInterceptor.class);
|
||||||
private Class<?>[] myReturnStackTracesForExceptionTypes;
|
private Class<?>[] myReturnStackTracesForExceptionTypes;
|
||||||
|
|
||||||
/**
|
|
||||||
* If any server methods throw an exception which extends any of the given exception types, the exception
|
|
||||||
* stack trace will be returned to the user. This can be useful for helping to diagnose issues, but may
|
|
||||||
* not be desirable for production situations.
|
|
||||||
*
|
|
||||||
* @param theExceptionTypes The exception types for which to return the stack trace to the user.
|
|
||||||
* @return Returns an instance of this interceptor, to allow for easy method chaining.
|
|
||||||
*/
|
|
||||||
public ExceptionHandlingInterceptor setReturnStackTracesForExceptionTypes(Class<?>... theExceptionTypes) {
|
|
||||||
myReturnStackTracesForExceptionTypes = theExceptionTypes;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handleException(RequestDetails theRequestDetails, Throwable theException, HttpServletRequest theRequest, HttpServletResponse theResponse) throws ServletException, IOException {
|
public boolean handleException(RequestDetails theRequestDetails, Throwable theException, HttpServletRequest theRequest, HttpServletResponse theResponse) throws ServletException, IOException {
|
||||||
BaseOperationOutcome oo = null;
|
IBaseOperationOutcome oo = null;
|
||||||
int statusCode = Constants.STATUS_HTTP_500_INTERNAL_ERROR;
|
int statusCode = Constants.STATUS_HTTP_500_INTERNAL_ERROR;
|
||||||
|
|
||||||
FhirContext ctx = theRequestDetails.getServer().getFhirContext();
|
FhirContext ctx = theRequestDetails.getServer().getFhirContext();
|
||||||
|
@ -78,34 +66,31 @@ public class ExceptionHandlingInterceptor extends InterceptorAdapter {
|
||||||
*/
|
*/
|
||||||
if (oo == null) {
|
if (oo == null) {
|
||||||
try {
|
try {
|
||||||
oo = (BaseOperationOutcome) ctx.getResourceDefinition("OperationOutcome").getImplementingClass().newInstance();
|
RuntimeResourceDefinition ooDef = ctx.getResourceDefinition("OperationOutcome");
|
||||||
|
oo = (IBaseOperationOutcome) ooDef.getImplementingClass().newInstance();
|
||||||
|
|
||||||
|
if (theException instanceof InternalErrorException) {
|
||||||
|
ourLog.error("Failure during REST processing", theException);
|
||||||
|
populateDetails(ctx, theException, oo);
|
||||||
|
} else if (theException instanceof BaseServerResponseException) {
|
||||||
|
ourLog.warn("Failure during REST processing: {}", theException);
|
||||||
|
BaseServerResponseException baseServerResponseException = (BaseServerResponseException) theException;
|
||||||
|
statusCode = baseServerResponseException.getStatusCode();
|
||||||
|
populateDetails(ctx, theException, oo);
|
||||||
|
if (baseServerResponseException.getAdditionalMessages() != null) {
|
||||||
|
for (String next : baseServerResponseException.getAdditionalMessages()) {
|
||||||
|
OperationOutcomeUtil.addIssue(ctx, oo, "error", next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ourLog.error("Failure during REST processing: " + theException.toString(), theException);
|
||||||
|
populateDetails(ctx, theException, oo);
|
||||||
|
statusCode = Constants.STATUS_HTTP_500_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
ourLog.error("Failed to instantiate OperationOutcome resource instance", e1);
|
ourLog.error("Failed to instantiate OperationOutcome resource instance", e1);
|
||||||
throw new ServletException("Failed to instantiate OperationOutcome resource instance", e1);
|
throw new ServletException("Failed to instantiate OperationOutcome resource instance", e1);
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseIssue issue = oo.addIssue();
|
|
||||||
issue.getSeverityElement().setValue("error");
|
|
||||||
if (theException instanceof InternalErrorException) {
|
|
||||||
ourLog.error("Failure during REST processing", theException);
|
|
||||||
populateDetails(theException, issue);
|
|
||||||
} else if (theException instanceof BaseServerResponseException) {
|
|
||||||
ourLog.warn("Failure during REST processing: {}", theException);
|
|
||||||
BaseServerResponseException baseServerResponseException = (BaseServerResponseException) theException;
|
|
||||||
statusCode = baseServerResponseException.getStatusCode();
|
|
||||||
populateDetails(theException, issue);
|
|
||||||
if (baseServerResponseException.getAdditionalMessages() != null) {
|
|
||||||
for (String next : baseServerResponseException.getAdditionalMessages()) {
|
|
||||||
BaseIssue issue2 = oo.addIssue();
|
|
||||||
issue2.getSeverityElement().setValue("error");
|
|
||||||
issue2.setDetails(next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ourLog.error("Failure during REST processing: " + theException.toString(), theException);
|
|
||||||
populateDetails(theException, issue);
|
|
||||||
statusCode = Constants.STATUS_HTTP_500_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ourLog.error("Unknown error during processing", theException);
|
ourLog.error("Unknown error during processing", theException);
|
||||||
}
|
}
|
||||||
|
@ -127,30 +112,44 @@ public class ExceptionHandlingInterceptor extends InterceptorAdapter {
|
||||||
|
|
||||||
boolean requestIsBrowser = RestfulServer.requestIsBrowser(theRequest);
|
boolean requestIsBrowser = RestfulServer.requestIsBrowser(theRequest);
|
||||||
String fhirServerBase = theRequestDetails.getFhirServerBase();
|
String fhirServerBase = theRequestDetails.getFhirServerBase();
|
||||||
RestfulServerUtils.streamResponseAsResource(theRequestDetails.getServer(), theResponse, oo, RestfulServerUtils.determineResponseEncodingNoDefault(theRequest), true, requestIsBrowser,
|
RestfulServerUtils.streamResponseAsResource(theRequestDetails.getServer(), theResponse, oo, RestfulServerUtils.determineResponseEncodingNoDefault(theRequest), true, requestIsBrowser, NarrativeModeEnum.NORMAL, statusCode, false, fhirServerBase, false);
|
||||||
NarrativeModeEnum.NORMAL, statusCode, false, fhirServerBase, false);
|
|
||||||
|
|
||||||
// theResponse.setStatus(statusCode);
|
// theResponse.setStatus(statusCode);
|
||||||
// theRequestDetails.getServer().addHeadersToResponse(theResponse);
|
// theRequestDetails.getServer().addHeadersToResponse(theResponse);
|
||||||
// theResponse.setContentType("text/plain");
|
// theResponse.setContentType("text/plain");
|
||||||
// theResponse.setCharacterEncoding("UTF-8");
|
// theResponse.setCharacterEncoding("UTF-8");
|
||||||
// theResponse.getWriter().append(theException.getMessage());
|
// theResponse.getWriter().append(theException.getMessage());
|
||||||
// theResponse.getWriter().close();
|
// theResponse.getWriter().close();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateDetails(Throwable theException, BaseIssue issue) {
|
private void populateDetails(FhirContext theCtx, Throwable theException, IBaseOperationOutcome theOo) {
|
||||||
if (myReturnStackTracesForExceptionTypes != null) {
|
if (myReturnStackTracesForExceptionTypes != null) {
|
||||||
for (Class<?> next : myReturnStackTracesForExceptionTypes) {
|
for (Class<?> next : myReturnStackTracesForExceptionTypes) {
|
||||||
if (next.isAssignableFrom(theException.getClass())) {
|
if (next.isAssignableFrom(theException.getClass())) {
|
||||||
issue.getDetailsElement().setValue(theException.getMessage() + "\n\n" + ExceptionUtils.getStackTrace(theException));
|
String detailsValue = theException.getMessage() + "\n\n" + ExceptionUtils.getStackTrace(theException);
|
||||||
|
OperationOutcomeUtil.addIssue(theCtx, theOo, "error", detailsValue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue.getDetailsElement().setValue(theException.getMessage());
|
OperationOutcomeUtil.addIssue(theCtx, theOo, "error", theException.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If any server methods throw an exception which extends any of the given exception types, the exception stack trace
|
||||||
|
* will be returned to the user. This can be useful for helping to diagnose issues, but may not be desirable for
|
||||||
|
* production situations.
|
||||||
|
*
|
||||||
|
* @param theExceptionTypes
|
||||||
|
* The exception types for which to return the stack trace to the user.
|
||||||
|
* @return Returns an instance of this interceptor, to allow for easy method chaining.
|
||||||
|
*/
|
||||||
|
public ExceptionHandlingInterceptor setReturnStackTracesForExceptionTypes(Class<?>... theExceptionTypes) {
|
||||||
|
myReturnStackTracesForExceptionTypes = theExceptionTypes;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
package ca.uhn.fhir.util;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.api.IBase;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||||
|
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
||||||
|
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
|
/**
|
||||||
|
* Utilities for dealing with OperationOutcome resources across various model versions
|
||||||
|
*/
|
||||||
|
public class OperationOutcomeUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an issue to an OperationOutcome
|
||||||
|
*
|
||||||
|
* @param theCtx The fhir context
|
||||||
|
* @param theOperationOutcome The OO resource to add to
|
||||||
|
* @param theSeverity The severity (e.g. "error")
|
||||||
|
* @param theDetails The details string
|
||||||
|
*/
|
||||||
|
public static void addIssue(FhirContext theCtx, IBaseOperationOutcome theOperationOutcome, String theSeverity, String theDetails) {
|
||||||
|
IBase issue = createIssue(theCtx, theOperationOutcome);
|
||||||
|
populateDetails(theCtx, issue, theSeverity, theDetails, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an issue to an OperationOutcome
|
||||||
|
*
|
||||||
|
* @param theCtx The fhir context
|
||||||
|
* @param theOperationOutcome The OO resource to add to
|
||||||
|
* @param theSeverity The severity (e.g. "error")
|
||||||
|
* @param theDetails The details string
|
||||||
|
*/
|
||||||
|
public static void addIssue(FhirContext theCtx, IBaseOperationOutcome theOperationOutcome, String theSeverity, String theDetails, String theLocation) {
|
||||||
|
IBase issue = createIssue(theCtx, theOperationOutcome);
|
||||||
|
populateDetails(theCtx, issue, theSeverity, theDetails, theLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IBase createIssue(FhirContext theCtx, IBaseResource theOutcome) {
|
||||||
|
RuntimeResourceDefinition ooDef = theCtx.getResourceDefinition(theOutcome);
|
||||||
|
BaseRuntimeChildDefinition issueChild = ooDef.getChildByName("issue");
|
||||||
|
BaseRuntimeElementCompositeDefinition<?> issueElement = (BaseRuntimeElementCompositeDefinition<?>) issueChild.getChildByName("issue");
|
||||||
|
|
||||||
|
IBase issue = issueElement.newInstance();
|
||||||
|
issueChild.getMutator().addValue(theOutcome, issue);
|
||||||
|
return issue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void populateDetails(FhirContext theCtx, IBase theIssue, String theSeverity, String theDetails, String theLocation) {
|
||||||
|
BaseRuntimeElementCompositeDefinition<?> issueElement = (BaseRuntimeElementCompositeDefinition<?>) theCtx.getElementDefinition(theIssue.getClass());
|
||||||
|
BaseRuntimeChildDefinition detailsChild = issueElement.getChildByName("details");
|
||||||
|
BaseRuntimeElementDefinition<?> stringDef = theCtx.getElementDefinition("string");
|
||||||
|
BaseRuntimeChildDefinition severityChild = issueElement.getChildByName("severity");
|
||||||
|
BaseRuntimeChildDefinition locationChild = issueElement.getChildByName("location");
|
||||||
|
|
||||||
|
IPrimitiveType<?> severityElem = (IPrimitiveType<?>) severityChild.getChildByName("severity").newInstance(severityChild.getInstanceConstructorArguments());
|
||||||
|
severityElem.setValueAsString(theSeverity);
|
||||||
|
severityChild.getMutator().addValue(theIssue, severityElem);
|
||||||
|
|
||||||
|
IPrimitiveType<?> string = (IPrimitiveType<?>) stringDef.newInstance();
|
||||||
|
string.setValueAsString(theDetails);
|
||||||
|
detailsChild.getMutator().setValue(theIssue, string);
|
||||||
|
|
||||||
|
if (isNotBlank(theLocation)) {
|
||||||
|
IPrimitiveType<?> locationElem = (IPrimitiveType<?>) locationChild.getChildByName("location").newInstance(locationChild.getInstanceConstructorArguments());
|
||||||
|
locationElem.setValueAsString(theLocation);
|
||||||
|
locationChild.getMutator().addValue(theIssue, locationElem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given OperationOutcome has 1 or more Operation.issue repetitions
|
||||||
|
*/
|
||||||
|
public static boolean hasIssues(FhirContext theCtx, IBaseOperationOutcome theOutcome) {
|
||||||
|
if (theOutcome == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
RuntimeResourceDefinition ooDef = theCtx.getResourceDefinition(theOutcome);
|
||||||
|
BaseRuntimeChildDefinition issueChild = ooDef.getChildByName("issue");
|
||||||
|
return issueChild.getAccessor().getValues(theOutcome).size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFirstIssueDetails(FhirContext theCtx, IBaseOperationOutcome theOutcome) {
|
||||||
|
return getFirstIssueStringPart(theCtx, theOutcome, "details");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFirstIssueLocation(FhirContext theCtx, IBaseOperationOutcome theOutcome) {
|
||||||
|
return getFirstIssueStringPart(theCtx, theOutcome, "location");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getFirstIssueStringPart(FhirContext theCtx, IBaseOperationOutcome theOutcome, String name) {
|
||||||
|
if (theOutcome == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
RuntimeResourceDefinition ooDef = theCtx.getResourceDefinition(theOutcome);
|
||||||
|
BaseRuntimeChildDefinition issueChild = ooDef.getChildByName("issue");
|
||||||
|
|
||||||
|
List<IBase> issues = issueChild.getAccessor().getValues(theOutcome);
|
||||||
|
if (issues.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
IBase issue = issues.get(0);
|
||||||
|
BaseRuntimeElementCompositeDefinition<?> issueElement = (BaseRuntimeElementCompositeDefinition<?>) theCtx.getElementDefinition(issue.getClass());
|
||||||
|
BaseRuntimeChildDefinition detailsChild = issueElement.getChildByName(name);
|
||||||
|
|
||||||
|
List<IBase> details = detailsChild.getAccessor().getValues(issue);
|
||||||
|
if (details.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return ((IPrimitiveType<?>)details.get(0)).getValueAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1656,7 +1656,7 @@ public class XmlUtil {
|
||||||
version = attrs.getValue(BUNDLE_VERSION);
|
version = attrs.getValue(BUNDLE_VERSION);
|
||||||
}
|
}
|
||||||
if (ourLog.isDebugEnabled()) {
|
if (ourLog.isDebugEnabled()) {
|
||||||
ourLog.debug("FHIR XML procesing will use StAX implementation at {}\n Title: {}\n Symbolic name: {}\n Vendor: {}\n Version: {}", rootUrl, title, symbolicName, vendor, version);
|
ourLog.debug("FHIR XML procesing will use StAX implementation at {}\n Title: {}\n Symbolic name: {}\n Vendor: {}\n Version: {}", new Object[] { rootUrl, title, symbolicName, vendor, version } );
|
||||||
} else {
|
} else {
|
||||||
ourLog.info("FHIR XML procesing will use StAX implementation '{}' version '{}'", title, version);
|
ourLog.info("FHIR XML procesing will use StAX implementation '{}' version '{}'", title, version);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,13 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resource validator, which checks resources for compliance against various validation schemes (schemas, schematrons, etc.)
|
* Resource validator, which checks resources for compliance against various validation schemes (schemas, schematrons, etc.)
|
||||||
|
@ -148,9 +149,9 @@ public class FhirValidator {
|
||||||
next.validateBundle(ctx);
|
next.validateBundle(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseOperationOutcome oo = ctx.getOperationOutcome();
|
IBaseOperationOutcome oo = ctx.getOperationOutcome();
|
||||||
if (oo != null && oo.getIssue().size() > 0) {
|
if (oo != null && OperationOutcomeUtil.hasIssues(myContext, oo)) {
|
||||||
throw new ValidationFailureException(oo);
|
throw new ValidationFailureException(myContext, oo);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -168,7 +169,7 @@ public class FhirValidator {
|
||||||
public void validate(IResource theResource) throws ValidationFailureException {
|
public void validate(IResource theResource) throws ValidationFailureException {
|
||||||
ValidationResult validationResult = validateWithResult(theResource);
|
ValidationResult validationResult = validateWithResult(theResource);
|
||||||
if (!validationResult.isSuccessful()) {
|
if (!validationResult.isSuccessful()) {
|
||||||
throw new ValidationFailureException(validationResult.getOperationOutcome());
|
throw new ValidationFailureException(myContext, validationResult.getOperationOutcome());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,8 +190,8 @@ public class FhirValidator {
|
||||||
next.validateBundle(ctx);
|
next.validateBundle(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseOperationOutcome oo = ctx.getOperationOutcome();
|
IBaseOperationOutcome oo = ctx.getOperationOutcome();
|
||||||
return ValidationResult.valueOf(oo);
|
return ValidationResult.valueOf(myContext, oo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -209,7 +210,7 @@ public class FhirValidator {
|
||||||
next.validateResource(ctx);
|
next.validateResource(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseOperationOutcome oo = ctx.getOperationOutcome();
|
IBaseOperationOutcome oo = ctx.getOperationOutcome();
|
||||||
return ValidationResult.valueOf(oo);
|
return ValidationResult.valueOf(myContext, oo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
|
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
||||||
|
|
||||||
class SchemaBaseValidator implements IValidator {
|
class SchemaBaseValidator implements IValidator {
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SchemaBaseValidator.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SchemaBaseValidator.class);
|
||||||
|
@ -85,7 +86,8 @@ class SchemaBaseValidator implements IValidator {
|
||||||
validator.setErrorHandler(handler);
|
validator.setErrorHandler(handler);
|
||||||
String encodedResource = theContext.getXmlEncodedResource();
|
String encodedResource = theContext.getXmlEncodedResource();
|
||||||
|
|
||||||
// ourLog.info(new FhirContext().newXmlParser().setPrettyPrint(true).encodeBundleToString((Bundle) theContext.getResource()));
|
// ourLog.info(new FhirContext().newXmlParser().setPrettyPrint(true).encodeBundleToString((Bundle)
|
||||||
|
// theContext.getResource()));
|
||||||
|
|
||||||
validator.validate(new StreamSource(new StringReader(encodedResource)));
|
validator.validate(new StreamSource(new StringReader(encodedResource)));
|
||||||
} catch (SAXException e) {
|
} catch (SAXException e) {
|
||||||
|
@ -123,25 +125,25 @@ class SchemaBaseValidator implements IValidator {
|
||||||
private Source loadXml(String theVersion, String theSystemId, String theSchemaName) {
|
private Source loadXml(String theVersion, String theSystemId, String theSchemaName) {
|
||||||
String pathToBase = myCtx.getVersion().getPathToSchemaDefinitions() + '/' + theSchemaName;
|
String pathToBase = myCtx.getVersion().getPathToSchemaDefinitions() + '/' + theSchemaName;
|
||||||
ourLog.debug("Going to load resource: {}", pathToBase);
|
ourLog.debug("Going to load resource: {}", pathToBase);
|
||||||
InputStream baseIs = FhirValidator.class.getClassLoader().getResourceAsStream(pathToBase);
|
InputStream baseIs = FhirValidator.class.getResourceAsStream(pathToBase);
|
||||||
if (baseIs == null) {
|
if (baseIs == null) {
|
||||||
throw new InternalErrorException("No FHIR-BASE schema found");
|
throw new InternalErrorException("No FHIR-BASE schema found");
|
||||||
}
|
}
|
||||||
baseIs = new BOMInputStream(baseIs, false);
|
baseIs = new BOMInputStream(baseIs, false);
|
||||||
InputStreamReader baseReader = new InputStreamReader(baseIs, Charset.forName("UTF-8"));
|
InputStreamReader baseReader = new InputStreamReader(baseIs, Charset.forName("UTF-8"));
|
||||||
Source baseSource = new StreamSource(baseReader, theSystemId);
|
Source baseSource = new StreamSource(baseReader, theSystemId);
|
||||||
|
|
||||||
// String schema;
|
// String schema;
|
||||||
// try {
|
// try {
|
||||||
// schema = IOUtils.toString(baseIs, Charset.forName("UTF-8"));
|
// schema = IOUtils.toString(baseIs, Charset.forName("UTF-8"));
|
||||||
// } catch (IOException e) {
|
// } catch (IOException e) {
|
||||||
// throw new InternalErrorException(e);
|
// throw new InternalErrorException(e);
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// ourLog.info("Schema is:\n{}", schema);
|
// ourLog.info("Schema is:\n{}", schema);
|
||||||
//
|
//
|
||||||
// Source baseSource = new StreamSource(new StringReader(schema), theSystemId);
|
// Source baseSource = new StreamSource(new StringReader(schema), theSystemId);
|
||||||
// Source baseSource = new StreamSource(baseIs, theSystemId);
|
// Source baseSource = new StreamSource(baseIs, theSystemId);
|
||||||
return baseSource;
|
return baseSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,11 +169,10 @@ class SchemaBaseValidator implements IValidator {
|
||||||
myContext = theContext;
|
myContext = theContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addIssue(SAXParseException theException, String severity) {
|
private void addIssue(SAXParseException theException, String theSeverity) {
|
||||||
BaseIssue issue = myContext.getOperationOutcome().addIssue();
|
String details = theException.getLocalizedMessage();
|
||||||
issue.getSeverityElement().setValue(severity);
|
String location = "Line[" + theException.getLineNumber() + "] Col[" + theException.getColumnNumber() + "]";
|
||||||
issue.getDetailsElement().setValue(theException.getLocalizedMessage());
|
OperationOutcomeUtil.addIssue(myContext.getFhirContext(), myContext.getOperationOutcome(), theSeverity, details, location);
|
||||||
issue.addLocation("Line[" + theException.getLineNumber() + "] Col[" + theException.getColumnNumber() + "]");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -205,12 +206,12 @@ class SchemaBaseValidator implements IValidator {
|
||||||
input.setPublicId(thePublicId);
|
input.setPublicId(thePublicId);
|
||||||
input.setSystemId(theSystemId);
|
input.setSystemId(theSystemId);
|
||||||
input.setBaseURI(theBaseURI);
|
input.setBaseURI(theBaseURI);
|
||||||
// String pathToBase = "ca/uhn/fhir/model/" + myVersion + "/schema/" + theSystemId;
|
// String pathToBase = "ca/uhn/fhir/model/" + myVersion + "/schema/" + theSystemId;
|
||||||
String pathToBase = myCtx.getVersion().getPathToSchemaDefinitions() + '/' + theSystemId;
|
String pathToBase = myCtx.getVersion().getPathToSchemaDefinitions() + '/' + theSystemId;
|
||||||
|
|
||||||
ourLog.debug("Loading referenced schema file: " + pathToBase);
|
ourLog.debug("Loading referenced schema file: " + pathToBase);
|
||||||
|
|
||||||
InputStream baseIs = FhirValidator.class.getClassLoader().getResourceAsStream(pathToBase);
|
InputStream baseIs = FhirValidator.class.getResourceAsStream(pathToBase);
|
||||||
if (baseIs == null) {
|
if (baseIs == null) {
|
||||||
throw new InternalErrorException("Schema file not found: " + pathToBase);
|
throw new InternalErrorException("Schema file not found: " + pathToBase);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,8 @@ import org.oclc.purl.dsdl.svrl.SchematronOutputType;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.api.BundleEntry;
|
import ca.uhn.fhir.model.api.BundleEntry;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
||||||
|
|
||||||
import com.phloc.commons.error.IResourceError;
|
import com.phloc.commons.error.IResourceError;
|
||||||
import com.phloc.commons.error.IResourceErrorGroup;
|
import com.phloc.commons.error.IResourceErrorGroup;
|
||||||
|
@ -70,23 +70,25 @@ public class SchematronBaseValidator implements IValidator {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IResourceError next : errors.getAllErrors().getAllResourceErrors()) {
|
for (IResourceError next : errors.getAllErrors().getAllResourceErrors()) {
|
||||||
BaseIssue issue = theCtx.getOperationOutcome().addIssue();
|
String severity;
|
||||||
switch (next.getErrorLevel()) {
|
switch (next.getErrorLevel()) {
|
||||||
case ERROR:
|
case ERROR:
|
||||||
issue.getSeverityElement().setValue("error");
|
severity = ("error");
|
||||||
break;
|
break;
|
||||||
case FATAL_ERROR:
|
case FATAL_ERROR:
|
||||||
issue.getSeverityElement().setValue("fatal");
|
severity = ("fatal");
|
||||||
break;
|
break;
|
||||||
case WARN:
|
case WARN:
|
||||||
issue.getSeverityElement().setValue("warning");
|
severity = ("warning");
|
||||||
break;
|
break;
|
||||||
case INFO:
|
case INFO:
|
||||||
case SUCCESS:
|
case SUCCESS:
|
||||||
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
issue.getDetailsElement().setValue(next.getAsString(Locale.getDefault()));
|
String details = next.getAsString(Locale.getDefault());
|
||||||
|
OperationOutcomeUtil.addIssue(myCtx, theCtx.getOperationOutcome(), severity, details);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -107,7 +109,7 @@ public class SchematronBaseValidator implements IValidator {
|
||||||
|
|
||||||
String pathToBase = myCtx.getVersion().getPathToSchemaDefinitions() + '/' + theCtx.getFhirContext().getResourceDefinition(theCtx.getResource()).getBaseDefinition().getName().toLowerCase()
|
String pathToBase = myCtx.getVersion().getPathToSchemaDefinitions() + '/' + theCtx.getFhirContext().getResourceDefinition(theCtx.getResource()).getBaseDefinition().getName().toLowerCase()
|
||||||
+ ".sch";
|
+ ".sch";
|
||||||
InputStream baseIs = FhirValidator.class.getClassLoader().getResourceAsStream(pathToBase);
|
InputStream baseIs = FhirValidator.class.getResourceAsStream(pathToBase);
|
||||||
if (baseIs == null) {
|
if (baseIs == null) {
|
||||||
throw new InternalErrorException("No schematron found for resource type: "
|
throw new InternalErrorException("No schematron found for resource type: "
|
||||||
+ theCtx.getFhirContext().getResourceDefinition(theCtx.getResource()).getBaseDefinition().getImplementingClass().getCanonicalName());
|
+ theCtx.getFhirContext().getResourceDefinition(theCtx.getResource()).getBaseDefinition().getImplementingClass().getCanonicalName());
|
||||||
|
|
|
@ -20,18 +20,18 @@ package ca.uhn.fhir.validation;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
|
||||||
class ValidationContext<T> {
|
class ValidationContext<T> {
|
||||||
|
|
||||||
private final IEncoder myEncoder;
|
private final IEncoder myEncoder;
|
||||||
private final FhirContext myFhirContext;
|
private final FhirContext myFhirContext;
|
||||||
private BaseOperationOutcome myOperationOutcome;
|
private IBaseOperationOutcome myOperationOutcome;
|
||||||
private final T myResource;
|
private final T myResource;
|
||||||
private String myXmlEncodedResource;
|
private String myXmlEncodedResource;
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidationContext.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidationContext.class);
|
||||||
|
@ -45,10 +45,10 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
|
||||||
return myFhirContext;
|
return myFhirContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseOperationOutcome getOperationOutcome() {
|
public IBaseOperationOutcome getOperationOutcome() {
|
||||||
if (myOperationOutcome == null) {
|
if (myOperationOutcome == null) {
|
||||||
try {
|
try {
|
||||||
myOperationOutcome = (BaseOperationOutcome) myFhirContext.getResourceDefinition("OperationOutcome").getImplementingClass().newInstance();
|
myOperationOutcome = (IBaseOperationOutcome) myFhirContext.getResourceDefinition("OperationOutcome").getImplementingClass().newInstance();
|
||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
ourLog.error("Failed to instantiate OperationOutcome resource instance", e1);
|
ourLog.error("Failed to instantiate OperationOutcome resource instance", e1);
|
||||||
throw new InternalErrorException("Failed to instantiate OperationOutcome resource instance", e1);
|
throw new InternalErrorException("Failed to instantiate OperationOutcome resource instance", e1);
|
||||||
|
|
|
@ -20,20 +20,23 @@ package ca.uhn.fhir.validation;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
||||||
|
|
||||||
public class ValidationFailureException extends RuntimeException {
|
public class ValidationFailureException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private BaseOperationOutcome myOperationOutcome;
|
private IBaseOperationOutcome myOperationOutcome;
|
||||||
|
|
||||||
// public ValidationFailureException(String theProblem) {
|
// public ValidationFailureException(String theProblem) {
|
||||||
// this(theProblem, IssueSeverityEnum.FATAL, null);
|
// this(theProblem, IssueSeverityEnum.FATAL, null);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private static String toDescription(BaseOperationOutcome theOo) {
|
private static String toDescription(FhirContext theCtx, IBaseOperationOutcome theOo) {
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
b.append(theOo.getIssueFirstRep().getDetailsElement().getValue());
|
b.append(OperationOutcomeUtil.getFirstIssueDetails(theCtx, theOo));
|
||||||
// b.append(" - ");
|
// b.append(" - ");
|
||||||
// b.append(theOo.getIssueFirstRep().getLocationFirstRep().getValue());
|
// b.append(theOo.getIssueFirstRep().getLocationFirstRep().getValue());
|
||||||
return b.toString();
|
return b.toString();
|
||||||
|
@ -49,12 +52,12 @@ public class ValidationFailureException extends RuntimeException {
|
||||||
// myOperationOutcome.addIssue().setSeverity(theSeverity).setDetails(theProblem);
|
// myOperationOutcome.addIssue().setSeverity(theSeverity).setDetails(theProblem);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public ValidationFailureException(BaseOperationOutcome theOperationOutcome) {
|
public ValidationFailureException(FhirContext theCtx, IBaseOperationOutcome theOperationOutcome) {
|
||||||
super(toDescription(theOperationOutcome));
|
super(toDescription(theCtx, theOperationOutcome));
|
||||||
myOperationOutcome = theOperationOutcome;
|
myOperationOutcome = theOperationOutcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseOperationOutcome getOperationOutcome() {
|
public IBaseOperationOutcome getOperationOutcome() {
|
||||||
return myOperationOutcome;
|
return myOperationOutcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,10 @@ package ca.uhn.fhir.validation;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.util.OperationOutcomeUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulates the results of validation
|
* Encapsulates the results of validation
|
||||||
|
@ -29,50 +32,48 @@ import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
||||||
* @since 0.7
|
* @since 0.7
|
||||||
*/
|
*/
|
||||||
public class ValidationResult {
|
public class ValidationResult {
|
||||||
private BaseOperationOutcome myOperationOutcome;
|
private IBaseOperationOutcome myOperationOutcome;
|
||||||
private boolean isSuccessful;
|
private boolean myIsSuccessful;
|
||||||
|
private FhirContext myCtx;
|
||||||
|
|
||||||
private ValidationResult(BaseOperationOutcome myOperationOutcome, boolean isSuccessful) {
|
private ValidationResult(FhirContext theCtx, IBaseOperationOutcome theOperationOutcome, boolean isSuccessful) {
|
||||||
this.myOperationOutcome = myOperationOutcome;
|
this.myCtx = theCtx;
|
||||||
this.isSuccessful = isSuccessful;
|
this.myOperationOutcome = theOperationOutcome;
|
||||||
}
|
this.myIsSuccessful = isSuccessful;
|
||||||
|
}
|
||||||
|
|
||||||
public static ValidationResult valueOf(BaseOperationOutcome myOperationOutcome) {
|
public static ValidationResult valueOf(FhirContext theCtx, IBaseOperationOutcome myOperationOutcome) {
|
||||||
boolean noIssues = myOperationOutcome == null || myOperationOutcome.getIssue().isEmpty();
|
boolean noIssues = !OperationOutcomeUtil.hasIssues(theCtx, myOperationOutcome);
|
||||||
return new ValidationResult(myOperationOutcome, noIssues);
|
return new ValidationResult(theCtx, myOperationOutcome, noIssues);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseOperationOutcome getOperationOutcome() {
|
public IBaseOperationOutcome getOperationOutcome() {
|
||||||
return myOperationOutcome;
|
return myOperationOutcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ValidationResult{" +
|
return "ValidationResult{" + "myOperationOutcome=" + myOperationOutcome + ", isSuccessful=" + myIsSuccessful + ", description='" + toDescription() + '\'' + '}';
|
||||||
"myOperationOutcome=" + myOperationOutcome +
|
}
|
||||||
", isSuccessful=" + isSuccessful +
|
|
||||||
", description='" + toDescription() + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
private String toDescription() {
|
private String toDescription() {
|
||||||
StringBuilder b = new StringBuilder(100);
|
StringBuilder b = new StringBuilder(100);
|
||||||
if (myOperationOutcome != null && myOperationOutcome.getIssue().size() > 0) {
|
if (myOperationOutcome != null && OperationOutcomeUtil.hasIssues(myCtx, myOperationOutcome)) {
|
||||||
BaseOperationOutcome.BaseIssue issueFirstRep = myOperationOutcome.getIssueFirstRep();
|
b.append(OperationOutcomeUtil.getFirstIssueDetails(myCtx, myOperationOutcome));
|
||||||
b.append(issueFirstRep.getDetailsElement().getValue());
|
b.append(" - ");
|
||||||
b.append(" - ");
|
b.append(OperationOutcomeUtil.getFirstIssueLocation(myCtx, myOperationOutcome));
|
||||||
b.append(issueFirstRep.getLocationFirstRep().getValue());
|
} else {
|
||||||
}else {
|
b.append("No issues");
|
||||||
b.append("No issues");
|
}
|
||||||
}
|
return b.toString();
|
||||||
return b.toString();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Was the validation successful
|
* Was the validation successful
|
||||||
* @return true if the validation was successful
|
*
|
||||||
*/
|
* @return true if the validation was successful
|
||||||
public boolean isSuccessful() {
|
*/
|
||||||
return isSuccessful;
|
public boolean isSuccessful() {
|
||||||
}
|
return myIsSuccessful;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package org.hl7.fhir.instance.model.api;
|
||||||
|
|
||||||
|
|
||||||
|
public interface IBaseOperationOutcome extends IBaseResource {
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package org.hl7.fhir.instance.model.api;
|
package org.hl7.fhir.instance.model.api;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR - Core Library
|
* HAPI FHIR - Core Library
|
||||||
|
@ -21,11 +22,23 @@ package org.hl7.fhir.instance.model.api;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base interface for ID datatype.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* <b>Concrete Implementations:</b> This interface is often returned and/or accepted by methods in HAPI's API
|
||||||
|
* where either {@link ca.uhn.fhir.model.primitive.IdDt} (the HAPI structure ID type) or
|
||||||
|
* <code>org.hl7.fhir.instance.model.IdType</code> (the RI structure ID type) will be used, depending on
|
||||||
|
* which version of the strctures your application is using.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
public interface IIdType {
|
public interface IIdType {
|
||||||
|
|
||||||
boolean isEmpty();
|
boolean isEmpty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if the ID is a local reference (in other words, it begins with the '#' character)
|
||||||
|
*/
|
||||||
boolean isLocal();
|
boolean isLocal();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,8 +55,16 @@ public interface IIdType {
|
||||||
*/
|
*/
|
||||||
String getIdPart();
|
String getIdPart();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if this ID contains an actual ID part. For example, the ID part is
|
||||||
|
* the '123' in the following ID: <code>http://example.com/fhir/Patient/123/_history/55</code>
|
||||||
|
*/
|
||||||
boolean hasIdPart();
|
boolean hasIdPart();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the server base URL if this ID contains one. For example, the base URL is
|
||||||
|
* the 'http://example.com/fhir' in the following ID: <code>http://example.com/fhir/Patient/123/_history/55</code>
|
||||||
|
*/
|
||||||
String getBaseUrl();
|
String getBaseUrl();
|
||||||
|
|
||||||
IIdType toUnqualifiedVersionless();
|
IIdType toUnqualifiedVersionless();
|
||||||
|
@ -72,4 +93,10 @@ public interface IIdType {
|
||||||
|
|
||||||
Long getIdPartAsLong();
|
Long getIdPartAsLong();
|
||||||
|
|
||||||
|
boolean hasBaseUrl();
|
||||||
|
|
||||||
|
IIdType withVersion(String theVersion);
|
||||||
|
|
||||||
|
void applyTo(IBaseResource theResource);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,18 +62,17 @@
|
||||||
<version>${thymeleaf-version}</version>
|
<version>${thymeleaf-version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<!-- Use an older version of SLF4j -->
|
||||||
<groupId>org.slf4j</groupId>
|
<dependency>
|
||||||
<artifactId>jcl-over-slf4j</artifactId>
|
<groupId>org.slf4j</groupId>
|
||||||
<version>${slf4j_version}</version>
|
<artifactId>slf4j-api</artifactId>
|
||||||
</dependency>
|
<version>1.6.0</version>
|
||||||
<!-- <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-nop</artifactId>
|
</dependency>
|
||||||
<version>${slf4j_version}</version> </dependency> -->
|
<dependency>
|
||||||
<dependency>
|
<groupId>org.slf4j</groupId>
|
||||||
<groupId>ch.qos.logback</groupId>
|
<artifactId>slf4j-simple</artifactId>
|
||||||
<artifactId>logback-classic</artifactId>
|
<version>1.6.0</version>
|
||||||
<version>${logback_version}</version>
|
</dependency>
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Test Database -->
|
<!-- Test Database -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
<attribute name="maven.pomderived" value="true"/>
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
|
<classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.6.0/slf4j-api-1.6.0.jar"/>
|
||||||
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/hapi-fhir-base"/>
|
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/hapi-fhir-base"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||||
<attributes>
|
<attributes>
|
||||||
|
|
|
@ -140,7 +140,7 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
|
|
||||||
private ISearchParamExtractor mySearchParamExtractor;
|
private ISearchParamExtractor mySearchParamExtractor;
|
||||||
|
|
||||||
protected void createForcedIdIfNeeded(ResourceTable entity, IdDt id) {
|
protected void createForcedIdIfNeeded(ResourceTable entity, IIdType id) {
|
||||||
if (id.isEmpty() == false && id.hasIdPart()) {
|
if (id.isEmpty() == false && id.hasIdPart()) {
|
||||||
if (isValidPid(id)) {
|
if (isValidPid(id)) {
|
||||||
return;
|
return;
|
||||||
|
@ -276,13 +276,13 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
values.addAll(t.getValues(theResource, nextPathTrimmed));
|
values.addAll(t.getValues(theResource, nextPathTrimmed));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
|
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
|
||||||
ourLog.warn("Failed to index values from path[{}] in resource type[{}]: ", nextPathTrimmed, def.getName(), e.toString());
|
ourLog.warn("Failed to index values from path[{}] in resource type[{}]: ", new Object[] { nextPathTrimmed, def.getName(), e.toString() } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findMatchingTagIds(String theResourceName, IdDt theResourceId, Set<Long> tagIds, Class<? extends BaseTag> entityClass) {
|
private void findMatchingTagIds(String theResourceName, IIdType theResourceId, Set<Long> tagIds, Class<? extends BaseTag> entityClass) {
|
||||||
{
|
{
|
||||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||||
CriteriaQuery<Tuple> cq = builder.createTupleQuery();
|
CriteriaQuery<Tuple> cq = builder.createTupleQuery();
|
||||||
|
@ -375,7 +375,7 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TagList getTags(Class<? extends IResource> theResourceType, IdDt theResourceId) {
|
protected TagList getTags(Class<? extends IResource> theResourceType, IIdType theResourceId) {
|
||||||
String resourceName = null;
|
String resourceName = null;
|
||||||
if (theResourceType != null) {
|
if (theResourceType != null) {
|
||||||
resourceName = toResourceName(theResourceType);
|
resourceName = toResourceName(theResourceType);
|
||||||
|
@ -610,7 +610,7 @@ public abstract class BaseFhirDao implements IDao {
|
||||||
|
|
||||||
List<IdDt> profiles = ResourceMetadataKeyEnum.PROFILES.get(theResource);
|
List<IdDt> profiles = ResourceMetadataKeyEnum.PROFILES.get(theResource);
|
||||||
if (profiles != null) {
|
if (profiles != null) {
|
||||||
for (IdDt next : profiles) {
|
for (IIdType next : profiles) {
|
||||||
TagDefinition tag = getTag(TagTypeEnum.PROFILE, NS_JPA_PROFILE, next.getValue(), null);
|
TagDefinition tag = getTag(TagTypeEnum.PROFILE, NS_JPA_PROFILE, next.getValue(), null);
|
||||||
theEntity.addTag(tag);
|
theEntity.addTag(tag);
|
||||||
theEntity.setHasTags(true);
|
theEntity.setHasTags(true);
|
||||||
|
|
|
@ -577,7 +577,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
|
|
||||||
if (isBlank(ref.getChain())) {
|
if (isBlank(ref.getChain())) {
|
||||||
if (resourceId.contains("/")) {
|
if (resourceId.contains("/")) {
|
||||||
IdDt dt = new IdDt(resourceId);
|
IIdType dt = new IdDt(resourceId);
|
||||||
resourceId = dt.getIdPart();
|
resourceId = dt.getIdPart();
|
||||||
}
|
}
|
||||||
Long targetPid = translateForcedIdToPid(new IdDt(resourceId));
|
Long targetPid = translateForcedIdToPid(new IdDt(resourceId));
|
||||||
|
@ -780,7 +780,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addTag(IdDt theId, TagTypeEnum theTagType, String theScheme, String theTerm, String theLabel) {
|
public void addTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm, String theLabel) {
|
||||||
StopWatch w = new StopWatch();
|
StopWatch w = new StopWatch();
|
||||||
BaseHasResource entity = readEntity(theId);
|
BaseHasResource entity = readEntity(theId);
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
|
@ -1062,10 +1062,10 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DaoMethodOutcome delete(IdDt theId) {
|
public DaoMethodOutcome delete(IIdType theId) {
|
||||||
StopWatch w = new StopWatch();
|
StopWatch w = new StopWatch();
|
||||||
final ResourceTable entity = readEntityLatestVersion(theId);
|
final ResourceTable entity = readEntityLatestVersion(theId);
|
||||||
if (theId.hasVersionIdPart() && theId.getVersionIdPartAsLong().longValue() != entity.getVersion()) {
|
if (theId.hasVersionIdPart() && Long.parseLong(theId.getVersionIdPart()) != entity.getVersion()) {
|
||||||
throw new InvalidRequestException("Trying to update " + theId + " but this is not the current version");
|
throw new InvalidRequestException("Trying to update " + theId + " but this is not the current version");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1169,7 +1169,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TagList getTags(IdDt theResourceId) {
|
public TagList getTags(IIdType theResourceId) {
|
||||||
StopWatch w = new StopWatch();
|
StopWatch w = new StopWatch();
|
||||||
TagList retVal = super.getTags(myResourceType, theResourceId);
|
TagList retVal = super.getTags(myResourceType, theResourceId);
|
||||||
ourLog.info("Processed getTags on {} in {}ms", theResourceId, w.getMillisAndRestart());
|
ourLog.info("Processed getTags on {} in {}ms", theResourceId, w.getMillisAndRestart());
|
||||||
|
@ -1185,7 +1185,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBundleProvider history(final IdDt theId, final Date theSince) {
|
public IBundleProvider history(final IIdType theId, final Date theSince) {
|
||||||
final InstantDt end = createHistoryToTimestamp();
|
final InstantDt end = createHistoryToTimestamp();
|
||||||
final String resourceType = getContext().getResourceDefinition(myResourceType).getName();
|
final String resourceType = getContext().getResourceDefinition(myResourceType).getName();
|
||||||
|
|
||||||
|
@ -1375,7 +1375,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MetaDt metaAddOperation(IdDt theResourceId, MetaDt theMetaAdd) {
|
public MetaDt metaAddOperation(IIdType theResourceId, MetaDt theMetaAdd) {
|
||||||
StopWatch w = new StopWatch();
|
StopWatch w = new StopWatch();
|
||||||
BaseHasResource entity = readEntity(theResourceId);
|
BaseHasResource entity = readEntity(theResourceId);
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
|
@ -1415,7 +1415,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MetaDt metaDeleteOperation(IdDt theResourceId, MetaDt theMetaDel) {
|
public MetaDt metaDeleteOperation(IIdType theResourceId, MetaDt theMetaDel) {
|
||||||
StopWatch w = new StopWatch();
|
StopWatch w = new StopWatch();
|
||||||
BaseHasResource entity = readEntity(theResourceId);
|
BaseHasResource entity = readEntity(theResourceId);
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
|
@ -1461,7 +1461,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MetaDt metaGetOperation(IdDt theId) {
|
public MetaDt metaGetOperation(IIdType theId) {
|
||||||
Long pid = super.translateForcedIdToPid(theId);
|
Long pid = super.translateForcedIdToPid(theId);
|
||||||
|
|
||||||
String sql = "SELECT d FROM TagDefinition d WHERE d.myId IN (SELECT DISTINCT t.myTagId FROM ResourceTag t WHERE t.myResourceType = :res_type AND t.myResourceId = :res_id)";
|
String sql = "SELECT d FROM TagDefinition d WHERE d.myId IN (SELECT DISTINCT t.myTagId FROM ResourceTag t WHERE t.myResourceType = :res_type AND t.myResourceId = :res_id)";
|
||||||
|
@ -1494,7 +1494,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T read(IdDt theId) {
|
public T read(IIdType theId) {
|
||||||
validateResourceTypeAndThrowIllegalArgumentException(theId);
|
validateResourceTypeAndThrowIllegalArgumentException(theId);
|
||||||
|
|
||||||
StopWatch w = new StopWatch();
|
StopWatch w = new StopWatch();
|
||||||
|
@ -1513,7 +1513,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseHasResource readEntity(IdDt theId) {
|
public BaseHasResource readEntity(IIdType theId) {
|
||||||
boolean checkForForcedId = true;
|
boolean checkForForcedId = true;
|
||||||
|
|
||||||
BaseHasResource entity = readEntity(theId, checkForForcedId);
|
BaseHasResource entity = readEntity(theId, checkForForcedId);
|
||||||
|
@ -1522,13 +1522,13 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseHasResource readEntity(IdDt theId, boolean theCheckForForcedId) {
|
public BaseHasResource readEntity(IIdType theId, boolean theCheckForForcedId) {
|
||||||
validateResourceTypeAndThrowIllegalArgumentException(theId);
|
validateResourceTypeAndThrowIllegalArgumentException(theId);
|
||||||
|
|
||||||
Long pid = translateForcedIdToPid(theId);
|
Long pid = translateForcedIdToPid(theId);
|
||||||
BaseHasResource entity = myEntityManager.find(ResourceTable.class, pid);
|
BaseHasResource entity = myEntityManager.find(ResourceTable.class, pid);
|
||||||
if (theId.hasVersionIdPart()) {
|
if (theId.hasVersionIdPart()) {
|
||||||
if (entity.getVersion() != theId.getVersionIdPartAsLong()) {
|
if (entity.getVersion() != Long.parseLong(theId.getVersionIdPart())) {
|
||||||
entity = null;
|
entity = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1539,7 +1539,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
"SELECT t from ResourceHistoryTable t WHERE t.myResourceId = :RID AND t.myResourceType = :RTYP AND t.myResourceVersion = :RVER", ResourceHistoryTable.class);
|
"SELECT t from ResourceHistoryTable t WHERE t.myResourceId = :RID AND t.myResourceType = :RTYP AND t.myResourceVersion = :RVER", ResourceHistoryTable.class);
|
||||||
q.setParameter("RID", pid);
|
q.setParameter("RID", pid);
|
||||||
q.setParameter("RTYP", myResourceName);
|
q.setParameter("RTYP", myResourceName);
|
||||||
q.setParameter("RVER", theId.getVersionIdPartAsLong());
|
q.setParameter("RVER", Long.parseLong(theId.getVersionIdPart()));
|
||||||
entity = q.getSingleResult();
|
entity = q.getSingleResult();
|
||||||
}
|
}
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
|
@ -1555,7 +1555,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResourceTable readEntityLatestVersion(IdDt theId) {
|
private ResourceTable readEntityLatestVersion(IIdType theId) {
|
||||||
ResourceTable entity = myEntityManager.find(ResourceTable.class, translateForcedIdToPid(theId));
|
ResourceTable entity = myEntityManager.find(ResourceTable.class, translateForcedIdToPid(theId));
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
throw new ResourceNotFoundException(theId);
|
throw new ResourceNotFoundException(theId);
|
||||||
|
@ -1565,7 +1565,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeTag(IdDt theId, TagTypeEnum theTagType, String theScheme, String theTerm) {
|
public void removeTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm) {
|
||||||
StopWatch w = new StopWatch();
|
StopWatch w = new StopWatch();
|
||||||
BaseHasResource entity = readEntity(theId);
|
BaseHasResource entity = readEntity(theId);
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
|
@ -1728,7 +1728,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
previouslyLoadedPids.add(next.getIdElement().toUnqualifiedVersionless());
|
previouslyLoadedPids.add(next.getIdElement().toUnqualifiedVersionless());
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<IdDt> includePids = new HashSet<IdDt>();
|
Set<IIdType> includePids = new HashSet<IIdType>();
|
||||||
List<IBaseResource> resources = retVal;
|
List<IBaseResource> resources = retVal;
|
||||||
do {
|
do {
|
||||||
includePids.clear();
|
includePids.clear();
|
||||||
|
@ -1754,7 +1754,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
IdDt nextId = rr.getReference().toUnqualified();
|
IIdType nextId = rr.getReference().toUnqualified();
|
||||||
if (!previouslyLoadedPids.contains(nextId)) {
|
if (!previouslyLoadedPids.contains(nextId)) {
|
||||||
includePids.add(nextId);
|
includePids.add(nextId);
|
||||||
previouslyLoadedPids.add(nextId);
|
previouslyLoadedPids.add(nextId);
|
||||||
|
@ -1842,7 +1842,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
} else {
|
} else {
|
||||||
for (IQueryParameterType next : nextValue) {
|
for (IQueryParameterType next : nextValue) {
|
||||||
String value = next.getValueAsQueryToken();
|
String value = next.getValueAsQueryToken();
|
||||||
IdDt valueId = new IdDt(value);
|
IIdType valueId = new IdDt(value);
|
||||||
try {
|
try {
|
||||||
long valueLong = translateForcedIdToPid(valueId);
|
long valueLong = translateForcedIdToPid(valueId);
|
||||||
joinPids.add(valueLong);
|
joinPids.add(valueLong);
|
||||||
|
@ -2039,7 +2039,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
|
|
||||||
final ResourceTable entity;
|
final ResourceTable entity;
|
||||||
|
|
||||||
IdDt resourceId;
|
IIdType resourceId;
|
||||||
if (isNotBlank(theMatchUrl)) {
|
if (isNotBlank(theMatchUrl)) {
|
||||||
Set<Long> match = processMatchUrl(theMatchUrl, myResourceType);
|
Set<Long> match = processMatchUrl(theMatchUrl, myResourceType);
|
||||||
if (match.size() > 1) {
|
if (match.size() > 1) {
|
||||||
|
@ -2067,7 +2067,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resourceId.hasVersionIdPart() && resourceId.getVersionIdPartAsLong().longValue() != entity.getVersion()) {
|
if (resourceId.hasVersionIdPart() && Long.parseLong(resourceId.getVersionIdPart()) != entity.getVersion()) {
|
||||||
throw new InvalidRequestException("Trying to update " + resourceId + " but this is not the current version");
|
throw new InvalidRequestException("Trying to update " + resourceId + " but this is not the current version");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2078,7 +2078,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
return toMethodOutcome(savedEntity, theResource).setCreated(false);
|
return toMethodOutcome(savedEntity, theResource).setCreated(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateGivenIdIsAppropriateToRetrieveResource(IdDt theId, BaseHasResource entity) {
|
private void validateGivenIdIsAppropriateToRetrieveResource(IIdType theId, BaseHasResource entity) {
|
||||||
if (entity.getForcedId() != null) {
|
if (entity.getForcedId() != null) {
|
||||||
if (theId.isIdPartValidLong()) {
|
if (theId.isIdPartValidLong()) {
|
||||||
// This means that the resource with the given numeric ID exists, but it has a "forced ID", meaning that
|
// This means that the resource with the given numeric ID exists, but it has a "forced ID", meaning that
|
||||||
|
@ -2097,7 +2097,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateResourceTypeAndThrowIllegalArgumentException(IdDt theId) {
|
private void validateResourceTypeAndThrowIllegalArgumentException(IIdType theId) {
|
||||||
if (theId.hasResourceType() && !theId.getResourceType().equals(myResourceName)) {
|
if (theId.hasResourceType() && !theId.getResourceType().equals(myResourceName)) {
|
||||||
throw new IllegalArgumentException("Incorrect resource type (" + theId.getResourceType() + ") for this DAO, wanted: " + myResourceName);
|
throw new IllegalArgumentException("Incorrect resource type (" + theId.getResourceType() + ") for this DAO, wanted: " + myResourceName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class BaseSearchParamExtractor {
|
||||||
values.addAll(t.getValues(theResource, nextPathTrimmed));
|
values.addAll(t.getValues(theResource, nextPathTrimmed));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
|
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
|
||||||
ourLog.warn("Failed to index values from path[{}] in resource type[{}]: ", nextPathTrimmed, def.getName(), e.toString());
|
ourLog.warn("Failed to index values from path[{}] in resource type[{}]: ", new Object[] { nextPathTrimmed, def.getName(), e.toString() } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return values;
|
return values;
|
||||||
|
|
|
@ -32,6 +32,7 @@ import java.util.Set;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.springframework.jmx.access.InvalidInvocationException;
|
import org.springframework.jmx.access.InvalidInvocationException;
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
@ -363,7 +364,7 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
|
||||||
|
|
||||||
private static void handleTransactionCreateOrUpdateOutcome(Map<IdDt, IdDt> idSubstitutions, Map<IdDt, DaoMethodOutcome> idToPersistedOutcome, IdDt nextResourceId, DaoMethodOutcome outcome,
|
private static void handleTransactionCreateOrUpdateOutcome(Map<IdDt, IdDt> idSubstitutions, Map<IdDt, DaoMethodOutcome> idToPersistedOutcome, IdDt nextResourceId, DaoMethodOutcome outcome,
|
||||||
Entry newEntry, String theResourceType) {
|
Entry newEntry, String theResourceType) {
|
||||||
IdDt newId = outcome.getId().toUnqualifiedVersionless();
|
IdDt newId = (IdDt) outcome.getId().toUnqualifiedVersionless();
|
||||||
IdDt resourceId = isPlaceholder(nextResourceId) ? nextResourceId : nextResourceId.toUnqualifiedVersionless();
|
IdDt resourceId = isPlaceholder(nextResourceId) ? nextResourceId : nextResourceId.toUnqualifiedVersionless();
|
||||||
if (newId.equals(resourceId) == false) {
|
if (newId.equals(resourceId) == false) {
|
||||||
idSubstitutions.put(resourceId, newId);
|
idSubstitutions.put(resourceId, newId);
|
||||||
|
|
|
@ -24,19 +24,20 @@ import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
||||||
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.api.TagList;
|
import ca.uhn.fhir.model.api.TagList;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
|
||||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||||
|
|
||||||
public interface IFhirResourceDao<T extends IResource> extends IDao {
|
public interface IFhirResourceDao<T extends IResource> extends IDao {
|
||||||
|
|
||||||
void addTag(IdDt theId, TagTypeEnum theTagType, String theScheme, String theTerm, String theLabel);
|
void addTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm, String theLabel);
|
||||||
|
|
||||||
DaoMethodOutcome create(T theResource);
|
DaoMethodOutcome create(T theResource);
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ public interface IFhirResourceDao<T extends IResource> extends IDao {
|
||||||
*/
|
*/
|
||||||
DaoMethodOutcome create(T theResource, String theIfNoneExist, boolean thePerformIndexing);
|
DaoMethodOutcome create(T theResource, String theIfNoneExist, boolean thePerformIndexing);
|
||||||
|
|
||||||
DaoMethodOutcome delete(IdDt theResource);
|
DaoMethodOutcome delete(IIdType theResource);
|
||||||
|
|
||||||
DaoMethodOutcome deleteByUrl(String theString);
|
DaoMethodOutcome deleteByUrl(String theString);
|
||||||
|
|
||||||
|
@ -56,11 +57,11 @@ public interface IFhirResourceDao<T extends IResource> extends IDao {
|
||||||
|
|
||||||
Class<T> getResourceType();
|
Class<T> getResourceType();
|
||||||
|
|
||||||
TagList getTags(IdDt theResourceId);
|
TagList getTags(IIdType theResourceId);
|
||||||
|
|
||||||
IBundleProvider history(Date theSince);
|
IBundleProvider history(Date theSince);
|
||||||
|
|
||||||
IBundleProvider history(IdDt theId, Date theSince);
|
IBundleProvider history(IIdType theId, Date theSince);
|
||||||
|
|
||||||
IBundleProvider history(Long theId, Date theSince);
|
IBundleProvider history(Long theId, Date theSince);
|
||||||
|
|
||||||
|
@ -71,17 +72,17 @@ public interface IFhirResourceDao<T extends IResource> extends IDao {
|
||||||
* @throws ResourceNotFoundException
|
* @throws ResourceNotFoundException
|
||||||
* If the ID is not known to the server
|
* If the ID is not known to the server
|
||||||
*/
|
*/
|
||||||
T read(IdDt theId);
|
T read(IIdType theId);
|
||||||
|
|
||||||
BaseHasResource readEntity(IdDt theId);
|
BaseHasResource readEntity(IIdType theId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param theCheckForForcedId If true, this method should fail if the requested ID contains a numeric PID which exists, but is
|
* @param theCheckForForcedId If true, this method should fail if the requested ID contains a numeric PID which exists, but is
|
||||||
* obscured by a "forced ID" so should not exist as far as the outside world is concerned.
|
* obscured by a "forced ID" so should not exist as far as the outside world is concerned.
|
||||||
*/
|
*/
|
||||||
BaseHasResource readEntity(IdDt theId, boolean theCheckForForcedId);
|
BaseHasResource readEntity(IIdType theId, boolean theCheckForForcedId);
|
||||||
|
|
||||||
void removeTag(IdDt theId, TagTypeEnum theTagType, String theScheme, String theTerm);
|
void removeTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm);
|
||||||
|
|
||||||
IBundleProvider search(Map<String, IQueryParameterType> theParams);
|
IBundleProvider search(Map<String, IQueryParameterType> theParams);
|
||||||
|
|
||||||
|
@ -114,15 +115,15 @@ public interface IFhirResourceDao<T extends IResource> extends IDao {
|
||||||
/**
|
/**
|
||||||
* Not supported in DSTU1!
|
* Not supported in DSTU1!
|
||||||
*/
|
*/
|
||||||
MetaDt metaGetOperation(IdDt theId);
|
MetaDt metaGetOperation(IIdType theId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Not supported in DSTU1!
|
* Not supported in DSTU1!
|
||||||
*/
|
*/
|
||||||
MetaDt metaDeleteOperation(IdDt theId1, MetaDt theMetaDel);
|
MetaDt metaDeleteOperation(IIdType theId1, MetaDt theMetaDel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Not supported in DSTU1!
|
* Not supported in DSTU1!
|
||||||
*/
|
*/
|
||||||
MetaDt metaAddOperation(IdDt theId1, MetaDt theMetaAdd);
|
MetaDt metaAddOperation(IIdType theId1, MetaDt theMetaAdd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,38 +24,24 @@ import java.util.Date;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Required;
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.api.TagList;
|
import ca.uhn.fhir.model.api.TagList;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
|
|
||||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
|
||||||
import ca.uhn.fhir.model.dstu.valueset.IssueSeverityEnum;
|
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.rest.annotation.Create;
|
|
||||||
import ca.uhn.fhir.rest.annotation.Delete;
|
|
||||||
import ca.uhn.fhir.rest.annotation.GetTags;
|
import ca.uhn.fhir.rest.annotation.GetTags;
|
||||||
import ca.uhn.fhir.rest.annotation.History;
|
import ca.uhn.fhir.rest.annotation.History;
|
||||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||||
import ca.uhn.fhir.rest.annotation.Read;
|
import ca.uhn.fhir.rest.annotation.Read;
|
||||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
|
||||||
import ca.uhn.fhir.rest.annotation.Since;
|
import ca.uhn.fhir.rest.annotation.Since;
|
||||||
import ca.uhn.fhir.rest.annotation.Update;
|
|
||||||
import ca.uhn.fhir.rest.annotation.Validate;
|
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
|
||||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
|
||||||
|
|
||||||
public abstract class BaseJpaResourceProvider<T extends IResource> extends BaseJpaProvider implements IResourceProvider {
|
public abstract class BaseJpaResourceProvider<T extends IResource> extends BaseJpaProvider implements IResourceProvider {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseJpaResourceProvider.class);
|
|
||||||
|
|
||||||
private FhirContext myContext;
|
private FhirContext myContext;
|
||||||
|
|
||||||
private IFhirResourceDao<T> myDao;
|
private IFhirResourceDao<T> myDao;
|
||||||
|
|
||||||
public BaseJpaResourceProvider() {
|
public BaseJpaResourceProvider() {
|
||||||
|
@ -138,19 +124,4 @@ public abstract class BaseJpaResourceProvider<T extends IResource> extends BaseJ
|
||||||
myDao = theDao;
|
myDao = theDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate
|
|
||||||
public MethodOutcome validate(HttpServletRequest theRequest, @ResourceParam T theResource) {
|
|
||||||
startRequest(theRequest);
|
|
||||||
try {
|
|
||||||
MethodOutcome retVal = new MethodOutcome();
|
|
||||||
retVal.setOperationOutcome(new OperationOutcome());
|
|
||||||
BaseIssue issue = retVal.getOperationOutcome().addIssue();
|
|
||||||
issue.getSeverityElement().setValue("information");
|
|
||||||
issue.setDetails("Resource validates successfully");
|
|
||||||
return retVal;
|
|
||||||
} finally {
|
|
||||||
endRequest(theRequest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,12 +24,15 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.rest.annotation.Create;
|
import ca.uhn.fhir.rest.annotation.Create;
|
||||||
import ca.uhn.fhir.rest.annotation.Delete;
|
import ca.uhn.fhir.rest.annotation.Delete;
|
||||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||||
import ca.uhn.fhir.rest.annotation.Update;
|
import ca.uhn.fhir.rest.annotation.Update;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Validate;
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||||
|
|
||||||
|
@ -80,4 +83,19 @@ public class JpaResourceProviderDstu1<T extends IResource> extends BaseJpaResour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Validate
|
||||||
|
public MethodOutcome validate(HttpServletRequest theRequest, @ResourceParam T theResource) {
|
||||||
|
startRequest(theRequest);
|
||||||
|
try {
|
||||||
|
MethodOutcome retVal = new MethodOutcome();
|
||||||
|
retVal.setOperationOutcome(new OperationOutcome());
|
||||||
|
BaseIssue issue = ((OperationOutcome)retVal.getOperationOutcome()).addIssue();
|
||||||
|
issue.getSeverityElement().setValue("information");
|
||||||
|
issue.setDetails("Resource validates successfully (note that on this server, the DSTU1 endpoint validation only validates basic ability to parse the resource)");
|
||||||
|
return retVal;
|
||||||
|
} finally {
|
||||||
|
endRequest(theRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,6 +153,12 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Validate
|
||||||
|
public MethodOutcome validate(@ResourceParam T theResource, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode,
|
||||||
|
@Validate.Profile String theProfile) {
|
||||||
|
return validate(theResource, null, theRawResource, theEncoding, theMode, theProfile);
|
||||||
|
}
|
||||||
|
|
||||||
@Validate
|
@Validate
|
||||||
public MethodOutcome validate(@ResourceParam T theResource, @IdParam IdDt theId, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode,
|
public MethodOutcome validate(@ResourceParam T theResource, @IdParam IdDt theId, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode,
|
||||||
@Validate.Profile String theProfile) {
|
@Validate.Profile String theProfile) {
|
||||||
|
@ -177,7 +183,8 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
|
||||||
validator.setValidateAgainstStandardSchema(true);
|
validator.setValidateAgainstStandardSchema(true);
|
||||||
validator.setValidateAgainstStandardSchematron(true);
|
validator.setValidateAgainstStandardSchematron(true);
|
||||||
ValidationResult result = validator.validateWithResult(theResource);
|
ValidationResult result = validator.validateWithResult(theResource);
|
||||||
for (BaseIssue next : result.getOperationOutcome().getIssue()) {
|
OperationOutcome operationOutcome = (OperationOutcome) result.getOperationOutcome();
|
||||||
|
for (BaseIssue next : operationOutcome.getIssue()) {
|
||||||
oo.getIssue().add((Issue) next);
|
oo.getIssue().add((Issue) next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import org.hamcrest.core.StringContains;
|
import org.hamcrest.core.StringContains;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -46,7 +47,7 @@ public class FhirResourceDaoDstu1Test extends BaseJpaTest {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
p.setId("Patient/" + methodName);
|
p.setId("Patient/" + methodName);
|
||||||
IdDt id = ourPatientDao.create(p).getId();
|
IIdType id = ourPatientDao.create(p).getId();
|
||||||
ourLog.info("Created patient, got it: {}", id);
|
ourLog.info("Created patient, got it: {}", id);
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
|
@ -95,13 +96,13 @@ public class FhirResourceDaoDstu1Test extends BaseJpaTest {
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsIdWhichPointsToForcedId01");
|
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsIdWhichPointsToForcedId01");
|
||||||
p1.addName().addFamily("Tester").addGiven("testUpdateRejectsIdWhichPointsToForcedId01");
|
p1.addName().addFamily("Tester").addGiven("testUpdateRejectsIdWhichPointsToForcedId01");
|
||||||
p1.setId("ABABA");
|
p1.setId("ABABA");
|
||||||
IdDt p1id = ourPatientDao.create(p1).getId();
|
IIdType p1id = ourPatientDao.create(p1).getId();
|
||||||
assertEquals("ABABA", p1id.getIdPart());
|
assertEquals("ABABA", p1id.getIdPart());
|
||||||
|
|
||||||
Patient p2 = new Patient();
|
Patient p2 = new Patient();
|
||||||
p2.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsIdWhichPointsToForcedId02");
|
p2.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsIdWhichPointsToForcedId02");
|
||||||
p2.addName().addFamily("Tester").addGiven("testUpdateRejectsIdWhichPointsToForcedId02");
|
p2.addName().addFamily("Tester").addGiven("testUpdateRejectsIdWhichPointsToForcedId02");
|
||||||
IdDt p2id = ourPatientDao.create(p2).getId();
|
IIdType p2id = ourPatientDao.create(p2).getId();
|
||||||
long p1longId = p2id.getIdPartAsLong() - 1;
|
long p1longId = p2id.getIdPartAsLong() - 1;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,22 +1,7 @@
|
||||||
package ca.uhn.fhir.jpa.dao;
|
package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.contains;
|
import static org.hamcrest.Matchers.*;
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.junit.Assert.*;
|
||||||
import static org.hamcrest.Matchers.containsInRelativeOrder;
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.hamcrest.Matchers.endsWith;
|
|
||||||
import static org.hamcrest.Matchers.greaterThan;
|
|
||||||
import static org.hamcrest.Matchers.hasItem;
|
|
||||||
import static org.hamcrest.Matchers.hasItems;
|
|
||||||
import static org.hamcrest.Matchers.not;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertNotEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -30,6 +15,7 @@ import java.util.Set;
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
import org.hamcrest.core.StringContains;
|
import org.hamcrest.core.StringContains;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -113,10 +99,10 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
public void testQuestionnaireTitleGetsIndexed() {
|
public void testQuestionnaireTitleGetsIndexed() {
|
||||||
Questionnaire q = new Questionnaire();
|
Questionnaire q = new Questionnaire();
|
||||||
q.getGroup().setTitle("testQuestionnaireTitleGetsIndexedQ_TITLE");
|
q.getGroup().setTitle("testQuestionnaireTitleGetsIndexedQ_TITLE");
|
||||||
IdDt qid1 = ourQuestionnaireDao.create(q).getId().toUnqualifiedVersionless();
|
IIdType qid1 = ourQuestionnaireDao.create(q).getId().toUnqualifiedVersionless();
|
||||||
q = new Questionnaire();
|
q = new Questionnaire();
|
||||||
q.getGroup().setTitle("testQuestionnaireTitleGetsIndexedQ_NOTITLE");
|
q.getGroup().setTitle("testQuestionnaireTitleGetsIndexedQ_NOTITLE");
|
||||||
IdDt qid2 = ourQuestionnaireDao.create(q).getId().toUnqualifiedVersionless();
|
IIdType qid2 = ourQuestionnaireDao.create(q).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
IBundleProvider results = ourQuestionnaireDao.search("title", new StringParam("testQuestionnaireTitleGetsIndexedQ_TITLE"));
|
IBundleProvider results = ourQuestionnaireDao.search("title", new StringParam("testQuestionnaireTitleGetsIndexedQ_TITLE"));
|
||||||
assertEquals(1, results.size());
|
assertEquals(1, results.size());
|
||||||
|
@ -131,7 +117,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Observation o1 = new Observation();
|
Observation o1 = new Observation();
|
||||||
o1.getCode().addCoding().setSystem("foo").setCode("testChoiceParam01");
|
o1.getCode().addCoding().setSystem("foo").setCode("testChoiceParam01");
|
||||||
o1.setValue(new CodeableConceptDt("testChoiceParam01CCS", "testChoiceParam01CCV"));
|
o1.setValue(new CodeableConceptDt("testChoiceParam01CCS", "testChoiceParam01CCV"));
|
||||||
IdDt id1 = ourObservationDao.create(o1).getId();
|
IIdType id1 = ourObservationDao.create(o1).getId();
|
||||||
|
|
||||||
{
|
{
|
||||||
IBundleProvider found = ourObservationDao.search(Observation.SP_VALUE_CONCEPT, new TokenParam("testChoiceParam01CCS", "testChoiceParam01CCV"));
|
IBundleProvider found = ourObservationDao.search(Observation.SP_VALUE_CONCEPT, new TokenParam("testChoiceParam01CCS", "testChoiceParam01CCV"));
|
||||||
|
@ -145,7 +131,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Observation o2 = new Observation();
|
Observation o2 = new Observation();
|
||||||
o2.getCode().addCoding().setSystem("foo").setCode("testChoiceParam02");
|
o2.getCode().addCoding().setSystem("foo").setCode("testChoiceParam02");
|
||||||
o2.setValue(new PeriodDt().setStart(new DateTimeDt("2001-01-01")).setEnd(new DateTimeDt("2001-01-03")));
|
o2.setValue(new PeriodDt().setStart(new DateTimeDt("2001-01-01")).setEnd(new DateTimeDt("2001-01-03")));
|
||||||
IdDt id2 = ourObservationDao.create(o2).getId();
|
IIdType id2 = ourObservationDao.create(o2).getId();
|
||||||
|
|
||||||
{
|
{
|
||||||
IBundleProvider found = ourObservationDao.search(Observation.SP_VALUE_DATE, new DateParam("2001-01-02"));
|
IBundleProvider found = ourObservationDao.search(Observation.SP_VALUE_DATE, new DateParam("2001-01-02"));
|
||||||
|
@ -159,7 +145,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Observation o2 = new Observation();
|
Observation o2 = new Observation();
|
||||||
o2.getCode().addCoding().setSystem("foo").setCode("testChoiceParamDateAlt02");
|
o2.getCode().addCoding().setSystem("foo").setCode("testChoiceParamDateAlt02");
|
||||||
o2.setApplies(new DateTimeDt("2015-03-08T11:11:11"));
|
o2.setApplies(new DateTimeDt("2015-03-08T11:11:11"));
|
||||||
IdDt id2 = ourObservationDao.create(o2).getId();
|
IIdType id2 = ourObservationDao.create(o2).getId();
|
||||||
|
|
||||||
{
|
{
|
||||||
Set<Long> found = ourObservationDao.searchForIds(Observation.SP_DATE, new DateParam(">2001-01-02"));
|
Set<Long> found = ourObservationDao.searchForIds(Observation.SP_DATE, new DateParam(">2001-01-02"));
|
||||||
|
@ -176,7 +162,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Observation o3 = new Observation();
|
Observation o3 = new Observation();
|
||||||
o3.getCode().addCoding().setSystem("foo").setCode("testChoiceParam03");
|
o3.getCode().addCoding().setSystem("foo").setCode("testChoiceParam03");
|
||||||
o3.setValue(new QuantityDt(QuantityComparatorEnum.GREATERTHAN, 123.0, "foo", "bar").setCode("bar"));
|
o3.setValue(new QuantityDt(QuantityComparatorEnum.GREATERTHAN, 123.0, "foo", "bar").setCode("bar"));
|
||||||
IdDt id3 = ourObservationDao.create(o3).getId();
|
IIdType id3 = ourObservationDao.create(o3).getId();
|
||||||
|
|
||||||
{
|
{
|
||||||
IBundleProvider found = ourObservationDao.search(Observation.SP_VALUE_QUANTITY, new QuantityParam(">100", "foo", "bar"));
|
IBundleProvider found = ourObservationDao.search(Observation.SP_VALUE_QUANTITY, new QuantityParam(">100", "foo", "bar"));
|
||||||
|
@ -205,7 +191,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Observation o4 = new Observation();
|
Observation o4 = new Observation();
|
||||||
o4.getCode().addCoding().setSystem("foo").setCode("testChoiceParam04");
|
o4.getCode().addCoding().setSystem("foo").setCode("testChoiceParam04");
|
||||||
o4.setValue(new StringDt("testChoiceParam04Str"));
|
o4.setValue(new StringDt("testChoiceParam04Str"));
|
||||||
IdDt id4 = ourObservationDao.create(o4).getId();
|
IIdType id4 = ourObservationDao.create(o4).getId();
|
||||||
|
|
||||||
{
|
{
|
||||||
IBundleProvider found = ourObservationDao.search(Observation.SP_VALUE_STRING, new StringParam("testChoiceParam04Str"));
|
IBundleProvider found = ourObservationDao.search(Observation.SP_VALUE_STRING, new StringParam("testChoiceParam04Str"));
|
||||||
|
@ -249,7 +235,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
IdDt id = ourPatientDao.create(p).getId();
|
IIdType id = ourPatientDao.create(p).getId();
|
||||||
ourLog.info("Created patient, got it: {}", id);
|
ourLog.info("Created patient, got it: {}", id);
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
|
@ -438,9 +424,9 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
public void testDeleteResource() {
|
public void testDeleteResource() {
|
||||||
int initialHistory = ourPatientDao.history(null).size();
|
int initialHistory = ourPatientDao.history(null).size();
|
||||||
|
|
||||||
IdDt id1;
|
IIdType id1;
|
||||||
IdDt id2;
|
IIdType id2;
|
||||||
IdDt id2b;
|
IIdType id2b;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||||
|
@ -502,7 +488,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||||
patient.addName().addFamily("Tester_testDeleteThenUndelete").addGiven("Joe");
|
patient.addName().addFamily("Tester_testDeleteThenUndelete").addGiven("Joe");
|
||||||
IdDt id = ourPatientDao.create(patient).getId();
|
IIdType id = ourPatientDao.create(patient).getId();
|
||||||
assertThat(id.getValue(), endsWith("/_history/1"));
|
assertThat(id.getValue(), endsWith("/_history/1"));
|
||||||
|
|
||||||
// should be ok
|
// should be ok
|
||||||
|
@ -522,11 +508,11 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||||
patient.addName().addFamily("Tester_testDeleteThenUndelete").addGiven("Joe");
|
patient.addName().addFamily("Tester_testDeleteThenUndelete").addGiven("Joe");
|
||||||
patient.setId(id.toUnqualifiedVersionless());
|
patient.setId(id.toUnqualifiedVersionless());
|
||||||
IdDt id2 = ourPatientDao.update(patient).getId();
|
IIdType id2 = ourPatientDao.update(patient).getId();
|
||||||
|
|
||||||
assertThat(id2.getValue(), endsWith("/_history/3"));
|
assertThat(id2.getValue(), endsWith("/_history/3"));
|
||||||
|
|
||||||
IdDt gotId = ourPatientDao.read(id.toUnqualifiedVersionless()).getId();
|
IIdType gotId = ourPatientDao.read(id.toUnqualifiedVersionless()).getId();
|
||||||
assertEquals(id2, gotId);
|
assertEquals(id2, gotId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,7 +522,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
IdDt id = ourPatientDao.create(p).getId();
|
IIdType id = ourPatientDao.create(p).getId();
|
||||||
ourLog.info("Created patient, got it: {}", id);
|
ourLog.info("Created patient, got it: {}", id);
|
||||||
|
|
||||||
Bundle request = new Bundle();
|
Bundle request = new Bundle();
|
||||||
|
@ -569,8 +555,8 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHistoryByForcedId() {
|
public void testHistoryByForcedId() {
|
||||||
IdDt idv1;
|
IIdType idv1;
|
||||||
IdDt idv2;
|
IIdType idv2;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("testHistoryByForcedId");
|
patient.addIdentifier().setSystem("urn:system").setValue("testHistoryByForcedId");
|
||||||
|
@ -706,26 +692,26 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
public void testPersistResourceLink() {
|
public void testPersistResourceLink() {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("testPersistResourceLink01");
|
patient.addIdentifier().setSystem("urn:system").setValue("testPersistResourceLink01");
|
||||||
IdDt patientId01 = ourPatientDao.create(patient).getId();
|
IIdType patientId01 = ourPatientDao.create(patient).getId();
|
||||||
|
|
||||||
Patient patient02 = new Patient();
|
Patient patient02 = new Patient();
|
||||||
patient02.addIdentifier().setSystem("urn:system").setValue("testPersistResourceLink02");
|
patient02.addIdentifier().setSystem("urn:system").setValue("testPersistResourceLink02");
|
||||||
IdDt patientId02 = ourPatientDao.create(patient02).getId();
|
IIdType patientId02 = ourPatientDao.create(patient02).getId();
|
||||||
|
|
||||||
Observation obs01 = new Observation();
|
Observation obs01 = new Observation();
|
||||||
obs01.setApplies(new DateTimeDt(new Date()));
|
obs01.setApplies(new DateTimeDt(new Date()));
|
||||||
obs01.setSubject(new ResourceReferenceDt(patientId01));
|
obs01.setSubject(new ResourceReferenceDt(patientId01));
|
||||||
IdDt obsId01 = ourObservationDao.create(obs01).getId();
|
IIdType obsId01 = ourObservationDao.create(obs01).getId();
|
||||||
|
|
||||||
Observation obs02 = new Observation();
|
Observation obs02 = new Observation();
|
||||||
obs02.setApplies(new DateTimeDt(new Date()));
|
obs02.setApplies(new DateTimeDt(new Date()));
|
||||||
obs02.setSubject(new ResourceReferenceDt(patientId02));
|
obs02.setSubject(new ResourceReferenceDt(patientId02));
|
||||||
IdDt obsId02 = ourObservationDao.create(obs02).getId();
|
IIdType obsId02 = ourObservationDao.create(obs02).getId();
|
||||||
|
|
||||||
// Create another type, that shouldn't be returned
|
// Create another type, that shouldn't be returned
|
||||||
DiagnosticReport dr01 = new DiagnosticReport();
|
DiagnosticReport dr01 = new DiagnosticReport();
|
||||||
dr01.setSubject(new ResourceReferenceDt(patientId01));
|
dr01.setSubject(new ResourceReferenceDt(patientId01));
|
||||||
IdDt drId01 = ourDiagnosticReportDao.create(dr01).getId();
|
IIdType drId01 = ourDiagnosticReportDao.create(dr01).getId();
|
||||||
|
|
||||||
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] { patientId01, patientId02, obsId01, obsId02, drId01 });
|
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] { patientId01, patientId02, obsId01, obsId02, drId01 });
|
||||||
|
|
||||||
|
@ -871,12 +857,12 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testReadVorcedIdVersionHistory01");
|
p1.addIdentifier().setSystem("urn:system").setValue("testReadVorcedIdVersionHistory01");
|
||||||
p1.setId("testReadVorcedIdVersionHistory");
|
p1.setId("testReadVorcedIdVersionHistory");
|
||||||
IdDt p1id = ourPatientDao.update(p1).getId();
|
IIdType p1id = ourPatientDao.update(p1).getId();
|
||||||
assertEquals("testReadVorcedIdVersionHistory", p1id.getIdPart());
|
assertEquals("testReadVorcedIdVersionHistory", p1id.getIdPart());
|
||||||
|
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testReadVorcedIdVersionHistory02");
|
p1.addIdentifier().setSystem("urn:system").setValue("testReadVorcedIdVersionHistory02");
|
||||||
p1.setId(p1id);
|
p1.setId(p1id);
|
||||||
IdDt p1idv2 = ourPatientDao.update(p1).getId();
|
IIdType p1idv2 = ourPatientDao.update(p1).getId();
|
||||||
assertEquals("testReadVorcedIdVersionHistory", p1idv2.getIdPart());
|
assertEquals("testReadVorcedIdVersionHistory", p1idv2.getIdPart());
|
||||||
|
|
||||||
assertNotEquals(p1id.getValue(), p1idv2.getValue());
|
assertNotEquals(p1id.getValue(), p1idv2.getValue());
|
||||||
|
@ -894,7 +880,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
String methodName = "testReverseIncludes";
|
String methodName = "testReverseIncludes";
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.setName("X" + methodName + "X");
|
org.setName("X" + methodName + "X");
|
||||||
IdDt orgId = ourOrganizationDao.create(org).getId();
|
IIdType orgId = ourOrganizationDao.create(org).getId();
|
||||||
|
|
||||||
Patient pat = new Patient();
|
Patient pat = new Patient();
|
||||||
pat.addName().addFamily("X" + methodName + "X");
|
pat.addName().addFamily("X" + methodName + "X");
|
||||||
|
@ -917,7 +903,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
deleteEverything();
|
deleteEverything();
|
||||||
|
|
||||||
String methodName = "testResourceInstanceMetaOperation";
|
String methodName = "testResourceInstanceMetaOperation";
|
||||||
IdDt id1, id2;
|
IIdType id1, id2;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue(methodName);
|
patient.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
|
@ -1035,7 +1021,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
deleteEverything();
|
deleteEverything();
|
||||||
|
|
||||||
String methodName = "testResourceMetaOperation";
|
String methodName = "testResourceMetaOperation";
|
||||||
IdDt id1, id2;
|
IIdType id1, id2;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue(methodName);
|
patient.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
|
@ -1172,13 +1158,13 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchByIdParam() {
|
public void testSearchByIdParam() {
|
||||||
IdDt id1;
|
IIdType id1;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||||
id1 = ourPatientDao.create(patient).getId();
|
id1 = ourPatientDao.create(patient).getId();
|
||||||
}
|
}
|
||||||
IdDt id2;
|
IIdType id2;
|
||||||
{
|
{
|
||||||
Organization patient = new Organization();
|
Organization patient = new Organization();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||||
|
@ -1202,12 +1188,12 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Observation o1 = new Observation();
|
Observation o1 = new Observation();
|
||||||
o1.getCode().addCoding().setSystem("foo").setCode("testSearchCompositeParamN01");
|
o1.getCode().addCoding().setSystem("foo").setCode("testSearchCompositeParamN01");
|
||||||
o1.setValue(new StringDt("testSearchCompositeParamS01"));
|
o1.setValue(new StringDt("testSearchCompositeParamS01"));
|
||||||
IdDt id1 = ourObservationDao.create(o1).getId();
|
IIdType id1 = ourObservationDao.create(o1).getId();
|
||||||
|
|
||||||
Observation o2 = new Observation();
|
Observation o2 = new Observation();
|
||||||
o2.getCode().addCoding().setSystem("foo").setCode("testSearchCompositeParamN01");
|
o2.getCode().addCoding().setSystem("foo").setCode("testSearchCompositeParamN01");
|
||||||
o2.setValue(new StringDt("testSearchCompositeParamS02"));
|
o2.setValue(new StringDt("testSearchCompositeParamS02"));
|
||||||
IdDt id2 = ourObservationDao.create(o2).getId();
|
IIdType id2 = ourObservationDao.create(o2).getId();
|
||||||
|
|
||||||
{
|
{
|
||||||
TokenParam v0 = new TokenParam("foo", "testSearchCompositeParamN01");
|
TokenParam v0 = new TokenParam("foo", "testSearchCompositeParamN01");
|
||||||
|
@ -1232,12 +1218,12 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Observation o1 = new Observation();
|
Observation o1 = new Observation();
|
||||||
o1.getCode().addCoding().setSystem("foo").setCode("testSearchCompositeParamDateN01");
|
o1.getCode().addCoding().setSystem("foo").setCode("testSearchCompositeParamDateN01");
|
||||||
o1.setValue(new PeriodDt().setStart(new DateTimeDt("2001-01-01T11:11:11")));
|
o1.setValue(new PeriodDt().setStart(new DateTimeDt("2001-01-01T11:11:11")));
|
||||||
IdDt id1 = ourObservationDao.create(o1).getId().toUnqualifiedVersionless();
|
IIdType id1 = ourObservationDao.create(o1).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Observation o2 = new Observation();
|
Observation o2 = new Observation();
|
||||||
o2.getCode().addCoding().setSystem("foo").setCode("testSearchCompositeParamDateN01");
|
o2.getCode().addCoding().setSystem("foo").setCode("testSearchCompositeParamDateN01");
|
||||||
o2.setValue(new PeriodDt().setStart(new DateTimeDt("2001-01-01T12:12:12")));
|
o2.setValue(new PeriodDt().setStart(new DateTimeDt("2001-01-01T12:12:12")));
|
||||||
IdDt id2 = ourObservationDao.create(o2).getId().toUnqualifiedVersionless();
|
IIdType id2 = ourObservationDao.create(o2).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
{
|
{
|
||||||
TokenParam v0 = new TokenParam("foo", "testSearchCompositeParamDateN01");
|
TokenParam v0 = new TokenParam("foo", "testSearchCompositeParamDateN01");
|
||||||
|
@ -1271,7 +1257,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchLanguageParam() {
|
public void testSearchLanguageParam() {
|
||||||
IdDt id1;
|
IIdType id1;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.getLanguage().setValue("en_CA");
|
patient.getLanguage().setValue("en_CA");
|
||||||
|
@ -1279,7 +1265,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
patient.addName().addFamily("testSearchLanguageParam").addGiven("Joe");
|
patient.addName().addFamily("testSearchLanguageParam").addGiven("Joe");
|
||||||
id1 = ourPatientDao.create(patient).getId();
|
id1 = ourPatientDao.create(patient).getId();
|
||||||
}
|
}
|
||||||
IdDt id2;
|
IIdType id2;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.getLanguage().setValue("en_US");
|
patient.getLanguage().setValue("en_US");
|
||||||
|
@ -1318,14 +1304,14 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Thread.sleep(sleep);
|
Thread.sleep(sleep);
|
||||||
|
|
||||||
DateTimeDt beforeAny = new DateTimeDt(new Date(), TemporalPrecisionEnum.MILLI);
|
DateTimeDt beforeAny = new DateTimeDt(new Date(), TemporalPrecisionEnum.MILLI);
|
||||||
IdDt id1a;
|
IIdType id1a;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||||
patient.addName().addFamily(methodName).addGiven("Joe");
|
patient.addName().addFamily(methodName).addGiven("Joe");
|
||||||
id1a = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
id1a = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
|
||||||
}
|
}
|
||||||
IdDt id1b;
|
IIdType id1b;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||||
|
@ -1337,7 +1323,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
DateTimeDt beforeR2 = new DateTimeDt(new Date(), TemporalPrecisionEnum.MILLI);
|
DateTimeDt beforeR2 = new DateTimeDt(new Date(), TemporalPrecisionEnum.MILLI);
|
||||||
Thread.sleep(1100);
|
Thread.sleep(1100);
|
||||||
|
|
||||||
IdDt id2;
|
IIdType id2;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||||
|
@ -1347,33 +1333,33 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
{
|
{
|
||||||
SearchParameterMap params = new SearchParameterMap();
|
SearchParameterMap params = new SearchParameterMap();
|
||||||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||||
assertThat(patients, hasItems(id1a, id1b, id2));
|
assertThat(patients, hasItems(id1a, id1b, id2));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
SearchParameterMap params = new SearchParameterMap();
|
SearchParameterMap params = new SearchParameterMap();
|
||||||
params.setLastUpdated(new DateRangeParam(beforeAny, null));
|
params.setLastUpdated(new DateRangeParam(beforeAny, null));
|
||||||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||||
assertThat(patients, hasItems(id1a, id1b, id2));
|
assertThat(patients, hasItems(id1a, id1b, id2));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
SearchParameterMap params = new SearchParameterMap();
|
SearchParameterMap params = new SearchParameterMap();
|
||||||
params.setLastUpdated(new DateRangeParam(beforeR2, null));
|
params.setLastUpdated(new DateRangeParam(beforeR2, null));
|
||||||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||||
assertThat(patients, hasItems(id2));
|
assertThat(patients, hasItems(id2));
|
||||||
assertThat(patients, not(hasItems(id1a, id1b)));
|
assertThat(patients, not(hasItems(id1a, id1b)));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
SearchParameterMap params = new SearchParameterMap();
|
SearchParameterMap params = new SearchParameterMap();
|
||||||
params.setLastUpdated(new DateRangeParam(beforeAny, beforeR2));
|
params.setLastUpdated(new DateRangeParam(beforeAny, beforeR2));
|
||||||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||||
assertThat(patients.toString(), patients, not(hasItems(id2)));
|
assertThat(patients.toString(), patients, not(hasItems(id2)));
|
||||||
assertThat(patients.toString(), patients, (hasItems(id1a, id1b)));
|
assertThat(patients.toString(), patients, (hasItems(id1a, id1b)));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
SearchParameterMap params = new SearchParameterMap();
|
SearchParameterMap params = new SearchParameterMap();
|
||||||
params.setLastUpdated(new DateRangeParam(null, beforeR2));
|
params.setLastUpdated(new DateRangeParam(null, beforeR2));
|
||||||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||||
assertThat(patients, (hasItems(id1a, id1b)));
|
assertThat(patients, (hasItems(id1a, id1b)));
|
||||||
assertThat(patients, not(hasItems(id2)));
|
assertThat(patients, not(hasItems(id2)));
|
||||||
}
|
}
|
||||||
|
@ -1381,7 +1367,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchNameParam() {
|
public void testSearchNameParam() {
|
||||||
IdDt id1;
|
IIdType id1;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||||
|
@ -1433,12 +1419,12 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Encounter e1 = new Encounter();
|
Encounter e1 = new Encounter();
|
||||||
e1.addIdentifier().setSystem("foo").setValue("testSearchNumberParam01");
|
e1.addIdentifier().setSystem("foo").setValue("testSearchNumberParam01");
|
||||||
e1.getLength().setSystem(BaseFhirDao.UCUM_NS).setCode("min").setValue(4.0 * 24 * 60);
|
e1.getLength().setSystem(BaseFhirDao.UCUM_NS).setCode("min").setValue(4.0 * 24 * 60);
|
||||||
IdDt id1 = ourEncounterDao.create(e1).getId();
|
IIdType id1 = ourEncounterDao.create(e1).getId();
|
||||||
|
|
||||||
Encounter e2 = new Encounter();
|
Encounter e2 = new Encounter();
|
||||||
e2.addIdentifier().setSystem("foo").setValue("testSearchNumberParam02");
|
e2.addIdentifier().setSystem("foo").setValue("testSearchNumberParam02");
|
||||||
e2.getLength().setSystem(BaseFhirDao.UCUM_NS).setCode("year").setValue(2.0);
|
e2.getLength().setSystem(BaseFhirDao.UCUM_NS).setCode("year").setValue(2.0);
|
||||||
IdDt id2 = ourEncounterDao.create(e2).getId();
|
IIdType id2 = ourEncounterDao.create(e2).getId();
|
||||||
{
|
{
|
||||||
IBundleProvider found = ourEncounterDao.search(Encounter.SP_LENGTH, new NumberParam(">2"));
|
IBundleProvider found = ourEncounterDao.search(Encounter.SP_LENGTH, new NumberParam(">2"));
|
||||||
assertEquals(2, found.size());
|
assertEquals(2, found.size());
|
||||||
|
@ -1460,27 +1446,27 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithChainXX");
|
patient.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithChainXX");
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithChain01");
|
patient.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithChain01");
|
||||||
IdDt patientId01 = ourPatientDao.create(patient).getId();
|
IIdType patientId01 = ourPatientDao.create(patient).getId();
|
||||||
|
|
||||||
Patient patient02 = new Patient();
|
Patient patient02 = new Patient();
|
||||||
patient02.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithChainXX");
|
patient02.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithChainXX");
|
||||||
patient02.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithChain02");
|
patient02.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithChain02");
|
||||||
IdDt patientId02 = ourPatientDao.create(patient02).getId();
|
IIdType patientId02 = ourPatientDao.create(patient02).getId();
|
||||||
|
|
||||||
Observation obs01 = new Observation();
|
Observation obs01 = new Observation();
|
||||||
obs01.setApplies(new DateTimeDt(new Date()));
|
obs01.setApplies(new DateTimeDt(new Date()));
|
||||||
obs01.setSubject(new ResourceReferenceDt(patientId01));
|
obs01.setSubject(new ResourceReferenceDt(patientId01));
|
||||||
IdDt obsId01 = ourObservationDao.create(obs01).getId();
|
IIdType obsId01 = ourObservationDao.create(obs01).getId();
|
||||||
|
|
||||||
Observation obs02 = new Observation();
|
Observation obs02 = new Observation();
|
||||||
obs02.setApplies(new DateTimeDt(new Date()));
|
obs02.setApplies(new DateTimeDt(new Date()));
|
||||||
obs02.setSubject(new ResourceReferenceDt(patientId02));
|
obs02.setSubject(new ResourceReferenceDt(patientId02));
|
||||||
IdDt obsId02 = ourObservationDao.create(obs02).getId();
|
IIdType obsId02 = ourObservationDao.create(obs02).getId();
|
||||||
|
|
||||||
// Create another type, that shouldn't be returned
|
// Create another type, that shouldn't be returned
|
||||||
DiagnosticReport dr01 = new DiagnosticReport();
|
DiagnosticReport dr01 = new DiagnosticReport();
|
||||||
dr01.setSubject(new ResourceReferenceDt(patientId01));
|
dr01.setSubject(new ResourceReferenceDt(patientId01));
|
||||||
IdDt drId01 = ourDiagnosticReportDao.create(dr01).getId();
|
IIdType drId01 = ourDiagnosticReportDao.create(dr01).getId();
|
||||||
|
|
||||||
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] { patientId01, patientId02, obsId01, obsId02, drId01 });
|
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] { patientId01, patientId02, obsId01, obsId02, drId01 });
|
||||||
|
|
||||||
|
@ -1513,21 +1499,21 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addName().addFamily("testSearchResourceLinkWithChainWithMultipleTypes01");
|
patient.addName().addFamily("testSearchResourceLinkWithChainWithMultipleTypes01");
|
||||||
patient.addName().addFamily("testSearchResourceLinkWithChainWithMultipleTypesXX");
|
patient.addName().addFamily("testSearchResourceLinkWithChainWithMultipleTypesXX");
|
||||||
IdDt patientId01 = ourPatientDao.create(patient).getId();
|
IIdType patientId01 = ourPatientDao.create(patient).getId();
|
||||||
|
|
||||||
Location loc01 = new Location();
|
Location loc01 = new Location();
|
||||||
loc01.getNameElement().setValue("testSearchResourceLinkWithChainWithMultipleTypes01");
|
loc01.getNameElement().setValue("testSearchResourceLinkWithChainWithMultipleTypes01");
|
||||||
IdDt locId01 = ourLocationDao.create(loc01).getId();
|
IIdType locId01 = ourLocationDao.create(loc01).getId();
|
||||||
|
|
||||||
Observation obs01 = new Observation();
|
Observation obs01 = new Observation();
|
||||||
obs01.setApplies(new DateTimeDt(new Date()));
|
obs01.setApplies(new DateTimeDt(new Date()));
|
||||||
obs01.setSubject(new ResourceReferenceDt(patientId01));
|
obs01.setSubject(new ResourceReferenceDt(patientId01));
|
||||||
IdDt obsId01 = ourObservationDao.create(obs01).getId();
|
IIdType obsId01 = ourObservationDao.create(obs01).getId();
|
||||||
|
|
||||||
Observation obs02 = new Observation();
|
Observation obs02 = new Observation();
|
||||||
obs02.setApplies(new DateTimeDt(new Date()));
|
obs02.setApplies(new DateTimeDt(new Date()));
|
||||||
obs02.setSubject(new ResourceReferenceDt(locId01));
|
obs02.setSubject(new ResourceReferenceDt(locId01));
|
||||||
IdDt obsId02 = ourObservationDao.create(obs02).getId();
|
IIdType obsId02 = ourObservationDao.create(obs02).getId();
|
||||||
|
|
||||||
ourLog.info("P1[{}] L1[{}] Obs1[{}] Obs2[{}]", new Object[] { patientId01, locId01, obsId01, obsId02 });
|
ourLog.info("P1[{}] L1[{}] Obs1[{}] Obs2[{}]", new Object[] { patientId01, locId01, obsId01, obsId02 });
|
||||||
|
|
||||||
|
@ -1552,28 +1538,28 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
patient.setId("testSearchResourceLinkWithTextLogicalId01");
|
patient.setId("testSearchResourceLinkWithTextLogicalId01");
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithTextLogicalIdXX");
|
patient.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithTextLogicalIdXX");
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithTextLogicalId01");
|
patient.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithTextLogicalId01");
|
||||||
IdDt patientId01 = ourPatientDao.update(patient).getId();
|
IIdType patientId01 = ourPatientDao.update(patient).getId();
|
||||||
|
|
||||||
Patient patient02 = new Patient();
|
Patient patient02 = new Patient();
|
||||||
patient02.setId("testSearchResourceLinkWithTextLogicalId02");
|
patient02.setId("testSearchResourceLinkWithTextLogicalId02");
|
||||||
patient02.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithTextLogicalIdXX");
|
patient02.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithTextLogicalIdXX");
|
||||||
patient02.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithTextLogicalId02");
|
patient02.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithTextLogicalId02");
|
||||||
IdDt patientId02 = ourPatientDao.update(patient02).getId();
|
IIdType patientId02 = ourPatientDao.update(patient02).getId();
|
||||||
|
|
||||||
Observation obs01 = new Observation();
|
Observation obs01 = new Observation();
|
||||||
obs01.setApplies(new DateTimeDt(new Date()));
|
obs01.setApplies(new DateTimeDt(new Date()));
|
||||||
obs01.setSubject(new ResourceReferenceDt(patientId01));
|
obs01.setSubject(new ResourceReferenceDt(patientId01));
|
||||||
IdDt obsId01 = ourObservationDao.create(obs01).getId();
|
IIdType obsId01 = ourObservationDao.create(obs01).getId();
|
||||||
|
|
||||||
Observation obs02 = new Observation();
|
Observation obs02 = new Observation();
|
||||||
obs02.setApplies(new DateTimeDt(new Date()));
|
obs02.setApplies(new DateTimeDt(new Date()));
|
||||||
obs02.setSubject(new ResourceReferenceDt(patientId02));
|
obs02.setSubject(new ResourceReferenceDt(patientId02));
|
||||||
IdDt obsId02 = ourObservationDao.create(obs02).getId();
|
IIdType obsId02 = ourObservationDao.create(obs02).getId();
|
||||||
|
|
||||||
// Create another type, that shouldn't be returned
|
// Create another type, that shouldn't be returned
|
||||||
DiagnosticReport dr01 = new DiagnosticReport();
|
DiagnosticReport dr01 = new DiagnosticReport();
|
||||||
dr01.setSubject(new ResourceReferenceDt(patientId01));
|
dr01.setSubject(new ResourceReferenceDt(patientId01));
|
||||||
IdDt drId01 = ourDiagnosticReportDao.create(dr01).getId();
|
IIdType drId01 = ourDiagnosticReportDao.create(dr01).getId();
|
||||||
|
|
||||||
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] { patientId01, patientId02, obsId01, obsId02, drId01 });
|
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] { patientId01, patientId02, obsId01, obsId02, drId01 });
|
||||||
|
|
||||||
|
@ -1625,9 +1611,9 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchWithMissingString() {
|
public void testSearchWithMissingString() {
|
||||||
IdDt orgId = ourOrganizationDao.create(new Organization()).getId();
|
IIdType orgId = ourOrganizationDao.create(new Organization()).getId();
|
||||||
IdDt notMissing;
|
IIdType notMissing;
|
||||||
IdDt missing;
|
IIdType missing;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||||
|
@ -1647,7 +1633,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
StringParam param = new StringParam();
|
StringParam param = new StringParam();
|
||||||
param.setMissing(false);
|
param.setMissing(false);
|
||||||
params.put(Patient.SP_FAMILY, param);
|
params.put(Patient.SP_FAMILY, param);
|
||||||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||||
}
|
}
|
||||||
|
@ -1656,7 +1642,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
StringParam param = new StringParam();
|
StringParam param = new StringParam();
|
||||||
param.setMissing(true);
|
param.setMissing(true);
|
||||||
params.put(Patient.SP_FAMILY, param);
|
params.put(Patient.SP_FAMILY, param);
|
||||||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||||
assertThat(patients, containsInRelativeOrder(missing));
|
assertThat(patients, containsInRelativeOrder(missing));
|
||||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||||
}
|
}
|
||||||
|
@ -1664,8 +1650,8 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchWithMissingQuantity() {
|
public void testSearchWithMissingQuantity() {
|
||||||
IdDt notMissing;
|
IIdType notMissing;
|
||||||
IdDt missing;
|
IIdType missing;
|
||||||
{
|
{
|
||||||
Observation obs = new Observation();
|
Observation obs = new Observation();
|
||||||
obs.addIdentifier().setSystem("urn:system").setValue("001");
|
obs.addIdentifier().setSystem("urn:system").setValue("001");
|
||||||
|
@ -1683,7 +1669,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
QuantityParam param = new QuantityParam();
|
QuantityParam param = new QuantityParam();
|
||||||
param.setMissing(false);
|
param.setMissing(false);
|
||||||
params.put(Observation.SP_VALUE_QUANTITY, param);
|
params.put(Observation.SP_VALUE_QUANTITY, param);
|
||||||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
||||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||||
}
|
}
|
||||||
|
@ -1692,7 +1678,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
QuantityParam param = new QuantityParam();
|
QuantityParam param = new QuantityParam();
|
||||||
param.setMissing(true);
|
param.setMissing(true);
|
||||||
params.put(Observation.SP_VALUE_QUANTITY, param);
|
params.put(Observation.SP_VALUE_QUANTITY, param);
|
||||||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
||||||
assertThat(patients, containsInRelativeOrder(missing));
|
assertThat(patients, containsInRelativeOrder(missing));
|
||||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||||
}
|
}
|
||||||
|
@ -1700,8 +1686,8 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchWithToken() {
|
public void testSearchWithToken() {
|
||||||
IdDt notMissing;
|
IIdType notMissing;
|
||||||
IdDt missing;
|
IIdType missing;
|
||||||
{
|
{
|
||||||
Observation obs = new Observation();
|
Observation obs = new Observation();
|
||||||
obs.addIdentifier().setSystem("urn:system").setValue("001");
|
obs.addIdentifier().setSystem("urn:system").setValue("001");
|
||||||
|
@ -1719,7 +1705,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
TokenParam param = new TokenParam();
|
TokenParam param = new TokenParam();
|
||||||
param.setMissing(false);
|
param.setMissing(false);
|
||||||
params.put(Observation.SP_CODE, param);
|
params.put(Observation.SP_CODE, param);
|
||||||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
||||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||||
}
|
}
|
||||||
|
@ -1728,7 +1714,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
TokenParam param = new TokenParam();
|
TokenParam param = new TokenParam();
|
||||||
param.setMissing(true);
|
param.setMissing(true);
|
||||||
params.put(Observation.SP_CODE, param);
|
params.put(Observation.SP_CODE, param);
|
||||||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
|
||||||
assertThat(patients, containsInRelativeOrder(missing));
|
assertThat(patients, containsInRelativeOrder(missing));
|
||||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||||
}
|
}
|
||||||
|
@ -1736,9 +1722,9 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchWithMissingDate() {
|
public void testSearchWithMissingDate() {
|
||||||
IdDt orgId = ourOrganizationDao.create(new Organization()).getId();
|
IIdType orgId = ourOrganizationDao.create(new Organization()).getId();
|
||||||
IdDt notMissing;
|
IIdType notMissing;
|
||||||
IdDt missing;
|
IIdType missing;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||||
|
@ -1758,7 +1744,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
DateParam param = new DateParam();
|
DateParam param = new DateParam();
|
||||||
param.setMissing(false);
|
param.setMissing(false);
|
||||||
params.put(Patient.SP_BIRTHDATE, param);
|
params.put(Patient.SP_BIRTHDATE, param);
|
||||||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||||
}
|
}
|
||||||
|
@ -1767,7 +1753,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
DateParam param = new DateParam();
|
DateParam param = new DateParam();
|
||||||
param.setMissing(true);
|
param.setMissing(true);
|
||||||
params.put(Patient.SP_BIRTHDATE, param);
|
params.put(Patient.SP_BIRTHDATE, param);
|
||||||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||||
assertThat(patients, containsInRelativeOrder(missing));
|
assertThat(patients, containsInRelativeOrder(missing));
|
||||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||||
}
|
}
|
||||||
|
@ -1775,9 +1761,9 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchWithMissingReference() {
|
public void testSearchWithMissingReference() {
|
||||||
IdDt orgId = ourOrganizationDao.create(new Organization()).getId().toUnqualifiedVersionless();
|
IIdType orgId = ourOrganizationDao.create(new Organization()).getId().toUnqualifiedVersionless();
|
||||||
IdDt notMissing;
|
IIdType notMissing;
|
||||||
IdDt missing;
|
IIdType missing;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||||
|
@ -1797,7 +1783,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
ReferenceParam param = new ReferenceParam();
|
ReferenceParam param = new ReferenceParam();
|
||||||
param.setMissing(false);
|
param.setMissing(false);
|
||||||
params.put(Patient.SP_ORGANIZATION, param);
|
params.put(Patient.SP_ORGANIZATION, param);
|
||||||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||||
assertThat(patients, not(containsInRelativeOrder(missing)));
|
assertThat(patients, not(containsInRelativeOrder(missing)));
|
||||||
assertThat(patients, containsInRelativeOrder(notMissing));
|
assertThat(patients, containsInRelativeOrder(notMissing));
|
||||||
}
|
}
|
||||||
|
@ -1806,7 +1792,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
ReferenceParam param = new ReferenceParam();
|
ReferenceParam param = new ReferenceParam();
|
||||||
param.setMissing(true);
|
param.setMissing(true);
|
||||||
params.put(Patient.SP_ORGANIZATION, param);
|
params.put(Patient.SP_ORGANIZATION, param);
|
||||||
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
|
||||||
assertThat(patients, containsInRelativeOrder(missing));
|
assertThat(patients, containsInRelativeOrder(missing));
|
||||||
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
assertThat(patients, not(containsInRelativeOrder(notMissing)));
|
||||||
assertThat(patients, not(containsInRelativeOrder(orgId)));
|
assertThat(patients, not(containsInRelativeOrder(orgId)));
|
||||||
|
@ -1939,7 +1925,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchWithIncludes() {
|
public void testSearchWithIncludes() {
|
||||||
IdDt parentOrgId;
|
IIdType parentOrgId;
|
||||||
{
|
{
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.getNameElement().setValue("testSearchWithIncludes_O1Parent");
|
org.getNameElement().setValue("testSearchWithIncludes_O1Parent");
|
||||||
|
@ -1949,7 +1935,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.getNameElement().setValue("testSearchWithIncludes_O1");
|
org.getNameElement().setValue("testSearchWithIncludes_O1");
|
||||||
org.setPartOf(new ResourceReferenceDt(parentOrgId));
|
org.setPartOf(new ResourceReferenceDt(parentOrgId));
|
||||||
IdDt orgId = ourOrganizationDao.create(org).getId();
|
IIdType orgId = ourOrganizationDao.create(org).getId();
|
||||||
|
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||||
|
@ -2028,7 +2014,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.setId("testSearchWithIncludesThatHaveTextId_id1");
|
org.setId("testSearchWithIncludesThatHaveTextId_id1");
|
||||||
org.getNameElement().setValue("testSearchWithIncludesThatHaveTextId_O1");
|
org.getNameElement().setValue("testSearchWithIncludesThatHaveTextId_O1");
|
||||||
IdDt orgId = ourOrganizationDao.update(org).getId();
|
IIdType orgId = ourOrganizationDao.update(org).getId();
|
||||||
assertThat(orgId.getValue(), endsWith("Organization/testSearchWithIncludesThatHaveTextId_id1/_history/1"));
|
assertThat(orgId.getValue(), endsWith("Organization/testSearchWithIncludesThatHaveTextId_id1/_history/1"));
|
||||||
|
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
@ -2066,26 +2052,26 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
|
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
|
||||||
p.addName().addFamily("testSortF1").addGiven("testSortG1");
|
p.addName().addFamily("testSortF1").addGiven("testSortG1");
|
||||||
p.setBirthDate(new DateDt("2001-01-01"));
|
p.setBirthDate(new DateDt("2001-01-01"));
|
||||||
IdDt id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
// Create out of order
|
// Create out of order
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
|
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
|
||||||
p.addName().addFamily("testSortF2").addGiven("testSortG2");
|
p.addName().addFamily("testSortF2").addGiven("testSortG2");
|
||||||
p.setBirthDate(new DateDt("2001-01-03"));
|
p.setBirthDate(new DateDt("2001-01-03"));
|
||||||
IdDt id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
|
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
|
||||||
p.addName().addFamily("testSortF3").addGiven("testSortG3");
|
p.addName().addFamily("testSortF3").addGiven("testSortG3");
|
||||||
p.setBirthDate(new DateDt("2001-01-02"));
|
p.setBirthDate(new DateDt("2001-01-02"));
|
||||||
IdDt id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
|
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
|
||||||
IdDt id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
List<IdDt> actual;
|
List<IIdType> actual;
|
||||||
SearchParameterMap pm;
|
SearchParameterMap pm;
|
||||||
|
|
||||||
pm = new SearchParameterMap();
|
pm = new SearchParameterMap();
|
||||||
|
@ -2117,28 +2103,28 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
IdDt id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
IdDt id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.setId(methodName);
|
p.setId(methodName);
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
IdDt idMethodName = ourPatientDao.update(p).getId().toUnqualifiedVersionless();
|
IIdType idMethodName = ourPatientDao.update(p).getId().toUnqualifiedVersionless();
|
||||||
assertEquals(methodName, idMethodName.getIdPart());
|
assertEquals(methodName, idMethodName.getIdPart());
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
IdDt id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
IdDt id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
SearchParameterMap pm;
|
SearchParameterMap pm;
|
||||||
List<IdDt> actual;
|
List<IIdType> actual;
|
||||||
|
|
||||||
pm = new SearchParameterMap();
|
pm = new SearchParameterMap();
|
||||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", methodName));
|
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", methodName));
|
||||||
|
@ -2167,25 +2153,25 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
|
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
|
||||||
p.addName().addFamily("testSortF1").addGiven("testSortG1");
|
p.addName().addFamily("testSortF1").addGiven("testSortG1");
|
||||||
IdDt id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
// Create out of order
|
// Create out of order
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
|
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
|
||||||
p.addName().addFamily("testSortF3").addGiven("testSortG3");
|
p.addName().addFamily("testSortF3").addGiven("testSortG3");
|
||||||
IdDt id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
|
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
|
||||||
p.addName().addFamily("testSortF2").addGiven("testSortG2");
|
p.addName().addFamily("testSortF2").addGiven("testSortG2");
|
||||||
IdDt id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
|
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
|
||||||
IdDt id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
SearchParameterMap pm;
|
SearchParameterMap pm;
|
||||||
List<IdDt> actual;
|
List<IIdType> actual;
|
||||||
|
|
||||||
pm = new SearchParameterMap();
|
pm = new SearchParameterMap();
|
||||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", "testSortByString"));
|
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", "testSortByString"));
|
||||||
|
@ -2214,36 +2200,36 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
String methodName = "testSortByReference";
|
String methodName = "testSortByReference";
|
||||||
|
|
||||||
Organization o1 = new Organization();
|
Organization o1 = new Organization();
|
||||||
IdDt oid1 = ourOrganizationDao.create(o1).getId().toUnqualifiedVersionless();
|
IIdType oid1 = ourOrganizationDao.create(o1).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Organization o2 = new Organization();
|
Organization o2 = new Organization();
|
||||||
IdDt oid2 = ourOrganizationDao.create(o2).getId().toUnqualifiedVersionless();
|
IIdType oid2 = ourOrganizationDao.create(o2).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
p.addName().addFamily("testSortF1").addGiven("testSortG1");
|
p.addName().addFamily("testSortF1").addGiven("testSortG1");
|
||||||
p.getManagingOrganization().setReference(oid1);
|
p.getManagingOrganization().setReference(oid1);
|
||||||
IdDt id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
p.addName().addFamily("testSortF2").addGiven("testSortG2");
|
p.addName().addFamily("testSortF2").addGiven("testSortG2");
|
||||||
p.getManagingOrganization().setReference(oid2);
|
p.getManagingOrganization().setReference(oid2);
|
||||||
IdDt id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
p.addName().addFamily("testSortF3").addGiven("testSortG3");
|
p.addName().addFamily("testSortF3").addGiven("testSortG3");
|
||||||
p.getManagingOrganization().setReference(oid1);
|
p.getManagingOrganization().setReference(oid1);
|
||||||
IdDt id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
p.getManagingOrganization().setReference(oid2);
|
p.getManagingOrganization().setReference(oid2);
|
||||||
IdDt id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
IIdType id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
SearchParameterMap pm;
|
SearchParameterMap pm;
|
||||||
List<IdDt> actual;
|
List<IIdType> actual;
|
||||||
|
|
||||||
pm = new SearchParameterMap();
|
pm = new SearchParameterMap();
|
||||||
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", methodName));
|
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", methodName));
|
||||||
|
@ -2274,13 +2260,13 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
public void testStoreUnversionedResources() {
|
public void testStoreUnversionedResources() {
|
||||||
Organization o1 = new Organization();
|
Organization o1 = new Organization();
|
||||||
o1.getNameElement().setValue("AAA");
|
o1.getNameElement().setValue("AAA");
|
||||||
IdDt o1id = ourOrganizationDao.create(o1).getId();
|
IIdType o1id = ourOrganizationDao.create(o1).getId();
|
||||||
assertTrue(o1id.hasVersionIdPart());
|
assertTrue(o1id.hasVersionIdPart());
|
||||||
|
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addName().addFamily("AAAA");
|
p1.addName().addFamily("AAAA");
|
||||||
p1.getManagingOrganization().setReference(o1id);
|
p1.getManagingOrganization().setReference(o1id);
|
||||||
IdDt p1id = ourPatientDao.create(p1).getId();
|
IIdType p1id = ourPatientDao.create(p1).getId();
|
||||||
|
|
||||||
p1 = ourPatientDao.read(p1id);
|
p1 = ourPatientDao.read(p1id);
|
||||||
|
|
||||||
|
@ -2296,7 +2282,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.setName("測試醫院");
|
org.setName("測試醫院");
|
||||||
org.addIdentifier().setSystem("urn:system").setValue("testStoreUtf8Characters_01");
|
org.addIdentifier().setSystem("urn:system").setValue("testStoreUtf8Characters_01");
|
||||||
IdDt orgId = ourOrganizationDao.create(org).getId();
|
IIdType orgId = ourOrganizationDao.create(org).getId();
|
||||||
|
|
||||||
Organization returned = ourOrganizationDao.read(orgId);
|
Organization returned = ourOrganizationDao.read(orgId);
|
||||||
String val = ourFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(returned);
|
String val = ourFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(returned);
|
||||||
|
@ -2357,7 +2343,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
ResourceMetadataKeyEnum.PROFILES.put(patient, profiles);
|
ResourceMetadataKeyEnum.PROFILES.put(patient, profiles);
|
||||||
|
|
||||||
MethodOutcome outcome = ourPatientDao.create(patient);
|
MethodOutcome outcome = ourPatientDao.create(patient);
|
||||||
IdDt patientId = outcome.getId();
|
IIdType patientId = outcome.getId();
|
||||||
assertNotNull(patientId);
|
assertNotNull(patientId);
|
||||||
assertFalse(patientId.isEmpty());
|
assertFalse(patientId.isEmpty());
|
||||||
|
|
||||||
|
@ -2534,7 +2520,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
IdDt id = ourPatientDao.create(p).getId();
|
IIdType id = ourPatientDao.create(p).getId();
|
||||||
ourLog.info("Created patient, got it: {}", id);
|
ourLog.info("Created patient, got it: {}", id);
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
|
@ -2560,7 +2546,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
p.addName().addFamily("Hello");
|
p.addName().addFamily("Hello");
|
||||||
p.setId("Patient/" + methodName);
|
p.setId("Patient/" + methodName);
|
||||||
|
|
||||||
IdDt id = ourPatientDao.update(p).getId();
|
IIdType id = ourPatientDao.update(p).getId();
|
||||||
assertEquals("Patient/" + methodName, id.toUnqualifiedVersionless().getValue());
|
assertEquals("Patient/" + methodName, id.toUnqualifiedVersionless().getValue());
|
||||||
|
|
||||||
p = ourPatientDao.read(id);
|
p = ourPatientDao.read(id);
|
||||||
|
@ -2587,7 +2573,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateMaintainsSearchParamsDstu2AAA");
|
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateMaintainsSearchParamsDstu2AAA");
|
||||||
p1.addName().addFamily("Tester").addGiven("testUpdateMaintainsSearchParamsDstu2AAA");
|
p1.addName().addFamily("Tester").addGiven("testUpdateMaintainsSearchParamsDstu2AAA");
|
||||||
IdDt p1id = ourPatientDao.create(p1).getId();
|
IIdType p1id = ourPatientDao.create(p1).getId();
|
||||||
|
|
||||||
Patient p2 = new Patient();
|
Patient p2 = new Patient();
|
||||||
p2.addIdentifier().setSystem("urn:system").setValue("testUpdateMaintainsSearchParamsDstu2BBB");
|
p2.addIdentifier().setSystem("urn:system").setValue("testUpdateMaintainsSearchParamsDstu2BBB");
|
||||||
|
@ -2601,7 +2587,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
// Update the name
|
// Update the name
|
||||||
p1.getNameFirstRep().getGivenFirstRep().setValue("testUpdateMaintainsSearchParamsDstu2BBB");
|
p1.getNameFirstRep().getGivenFirstRep().setValue("testUpdateMaintainsSearchParamsDstu2BBB");
|
||||||
MethodOutcome update2 = ourPatientDao.update(p1);
|
MethodOutcome update2 = ourPatientDao.update(p1);
|
||||||
IdDt p1id2 = update2.getId();
|
IIdType p1id2 = update2.getId();
|
||||||
|
|
||||||
ids = ourPatientDao.searchForIds(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2AAA"));
|
ids = ourPatientDao.searchForIds(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2AAA"));
|
||||||
assertEquals(0, ids.size());
|
assertEquals(0, ids.size());
|
||||||
|
@ -2623,7 +2609,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsInvalidTypes");
|
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsInvalidTypes");
|
||||||
p1.addName().addFamily("Tester").addGiven("testUpdateRejectsInvalidTypes");
|
p1.addName().addFamily("Tester").addGiven("testUpdateRejectsInvalidTypes");
|
||||||
IdDt p1id = ourPatientDao.create(p1).getId();
|
IIdType p1id = ourPatientDao.create(p1).getId();
|
||||||
|
|
||||||
Organization p2 = new Organization();
|
Organization p2 = new Organization();
|
||||||
p2.getNameElement().setValue("testUpdateRejectsInvalidTypes");
|
p2.getNameElement().setValue("testUpdateRejectsInvalidTypes");
|
||||||
|
@ -2664,10 +2650,10 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
return theSearch.getResources(0, theSearch.size());
|
return theSearch.getResources(0, theSearch.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<IdDt> toUnqualifiedVersionlessIds(IBundleProvider theFound) {
|
private List<IIdType> toUnqualifiedVersionlessIds(IBundleProvider theFound) {
|
||||||
List<IdDt> retVal = new ArrayList<IdDt>();
|
List<IIdType> retVal = new ArrayList<IIdType>();
|
||||||
for (IBaseResource next : theFound.getResources(0, theFound.size())) {
|
for (IBaseResource next : theFound.getResources(0, theFound.size())) {
|
||||||
retVal.add((IdDt) next.getIdElement().toUnqualifiedVersionless());
|
retVal.add((IIdType) next.getIdElement().toUnqualifiedVersionless());
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
@ -2707,7 +2693,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
|
||||||
ourLog.info("Initial size: " + value.size());
|
ourLog.info("Initial size: " + value.size());
|
||||||
for (IBaseResource next : value.getResources(0, value.size())) {
|
for (IBaseResource next : value.getResources(0, value.size())) {
|
||||||
ourLog.info("Deleting: {}", next.getIdElement());
|
ourLog.info("Deleting: {}", next.getIdElement());
|
||||||
ourDeviceDao.delete((IdDt) next.getIdElement());
|
ourDeviceDao.delete((IIdType) next.getIdElement());
|
||||||
}
|
}
|
||||||
|
|
||||||
value = ourDeviceDao.search(new SearchParameterMap());
|
value = ourDeviceDao.search(new SearchParameterMap());
|
||||||
|
|
|
@ -88,19 +88,19 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("testHistory");
|
patient.addIdentifier().setSystem("urn:system").setValue("testHistory");
|
||||||
patient.addName().addFamily("Tester").addGiven("Joe");
|
patient.addName().addFamily("Tester").addGiven("Joe");
|
||||||
IdDt pid = ourPatientDao.create(patient).getId().toVersionless();
|
IIdType pid = ourPatientDao.create(patient).getId().toVersionless();
|
||||||
|
|
||||||
Thread.sleep(10);
|
Thread.sleep(10);
|
||||||
patient.setId(pid);
|
patient.setId(pid);
|
||||||
IdDt newpid = ourPatientDao.update(patient).getId();
|
IIdType newpid = ourPatientDao.update(patient).getId();
|
||||||
|
|
||||||
Thread.sleep(10);
|
Thread.sleep(10);
|
||||||
patient.setId(pid);
|
patient.setId(pid);
|
||||||
IdDt newpid2 = ourPatientDao.update(patient).getId();
|
IIdType newpid2 = ourPatientDao.update(patient).getId();
|
||||||
|
|
||||||
Thread.sleep(10);
|
Thread.sleep(10);
|
||||||
patient.setId(pid);
|
patient.setId(pid);
|
||||||
IdDt newpid3 = ourPatientDao.update(patient).getId();
|
IIdType newpid3 = ourPatientDao.update(patient).getId();
|
||||||
|
|
||||||
IBundleProvider values = ourSystemDao.history(start);
|
IBundleProvider values = ourSystemDao.history(start);
|
||||||
assertEquals(4, values.size());
|
assertEquals(4, values.size());
|
||||||
|
@ -113,7 +113,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
|
||||||
|
|
||||||
Location loc = new Location();
|
Location loc = new Location();
|
||||||
loc.getAddress().addLine("AAA");
|
loc.getAddress().addLine("AAA");
|
||||||
IdDt lid = ourLocationDao.create(loc).getId();
|
IIdType lid = ourLocationDao.create(loc).getId();
|
||||||
|
|
||||||
Location loc2 = new Location();
|
Location loc2 = new Location();
|
||||||
loc2.getAddress().addLine("AAA");
|
loc2.getAddress().addLine("AAA");
|
||||||
|
@ -224,7 +224,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
|
||||||
Observation o1 = new Observation();
|
Observation o1 = new Observation();
|
||||||
o1.getName().setText("testGetAllTags02");
|
o1.getName().setText("testGetAllTags02");
|
||||||
ResourceMetadataKeyEnum.TAG_LIST.put(o1, tl2);
|
ResourceMetadataKeyEnum.TAG_LIST.put(o1, tl2);
|
||||||
IdDt o1id = ourObservationDao.create(o1).getId();
|
IIdType o1id = ourObservationDao.create(o1).getId();
|
||||||
assertTrue(o1id.getVersionIdPart() != null);
|
assertTrue(o1id.getVersionIdPart() != null);
|
||||||
|
|
||||||
TagList postSystemTl = ourSystemDao.getAllTags();
|
TagList postSystemTl = ourSystemDao.getAllTags();
|
||||||
|
@ -241,7 +241,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
|
||||||
|
|
||||||
o1.getResourceMetadata().remove(ResourceMetadataKeyEnum.TAG_LIST);
|
o1.getResourceMetadata().remove(ResourceMetadataKeyEnum.TAG_LIST);
|
||||||
o1.setId(o1id);
|
o1.setId(o1id);
|
||||||
IdDt o1id2 = ourObservationDao.update(o1).getId();
|
IIdType o1id2 = ourObservationDao.update(o1).getId();
|
||||||
assertTrue(o1id2.getVersionIdPart() != null);
|
assertTrue(o1id2.getVersionIdPart() != null);
|
||||||
|
|
||||||
tags2 = ourObservationDao.getTags(o1id);
|
tags2 = ourObservationDao.getTags(o1id);
|
||||||
|
|
|
@ -1,18 +1,7 @@
|
||||||
package ca.uhn.fhir.jpa.dao;
|
package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.*;
|
||||||
import static org.hamcrest.Matchers.emptyString;
|
import static org.junit.Assert.*;
|
||||||
import static org.hamcrest.Matchers.endsWith;
|
|
||||||
import static org.hamcrest.Matchers.greaterThan;
|
|
||||||
import static org.hamcrest.Matchers.not;
|
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
@ -21,11 +10,11 @@ import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
import org.springframework.jmx.access.InvalidInvocationException;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
|
@ -76,7 +65,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||||
assertEquals(0, published.size());
|
assertEquals(0, published.size());
|
||||||
|
|
||||||
String methodName = "testSystemMetaOperation";
|
String methodName = "testSystemMetaOperation";
|
||||||
IdDt id1;
|
IIdType id1;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue(methodName);
|
patient.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
|
@ -165,7 +154,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
p.setId("Patient/" + methodName);
|
p.setId("Patient/" + methodName);
|
||||||
IdDt id = ourPatientDao.update(p).getId();
|
IIdType id = ourPatientDao.update(p).getId();
|
||||||
ourLog.info("Created patient, got it: {}", id);
|
ourLog.info("Created patient, got it: {}", id);
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
|
@ -205,7 +194,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
IdDt id = ourPatientDao.create(p).getId();
|
IIdType id = ourPatientDao.create(p).getId();
|
||||||
ourLog.info("Created patient, got it: {}", id);
|
ourLog.info("Created patient, got it: {}", id);
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
|
@ -333,13 +322,13 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p1.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
IdDt id1 = ourPatientDao.create(p1).getId();
|
IIdType id1 = ourPatientDao.create(p1).getId();
|
||||||
ourLog.info("Created patient, got it: {}", id1);
|
ourLog.info("Created patient, got it: {}", id1);
|
||||||
|
|
||||||
Patient p2 = new Patient();
|
Patient p2 = new Patient();
|
||||||
p2.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p2.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
p2.setId("Patient/" + methodName);
|
p2.setId("Patient/" + methodName);
|
||||||
IdDt id2 = ourPatientDao.update(p2).getId();
|
IIdType id2 = ourPatientDao.update(p2).getId();
|
||||||
ourLog.info("Created patient, got it: {}", id2);
|
ourLog.info("Created patient, got it: {}", id2);
|
||||||
|
|
||||||
Bundle request = new Bundle();
|
Bundle request = new Bundle();
|
||||||
|
@ -379,7 +368,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
IdDt id = ourPatientDao.create(p).getId();
|
IIdType id = ourPatientDao.create(p).getId();
|
||||||
ourLog.info("Created patient, got it: {}", id);
|
ourLog.info("Created patient, got it: {}", id);
|
||||||
|
|
||||||
Bundle request = new Bundle();
|
Bundle request = new Bundle();
|
||||||
|
@ -420,7 +409,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
IdDt id = ourPatientDao.create(p).getId();
|
IIdType id = ourPatientDao.create(p).getId();
|
||||||
ourLog.info("Created patient, got it: {}", id);
|
ourLog.info("Created patient, got it: {}", id);
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
|
@ -466,7 +455,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
p.setId("Patient/" + methodName);
|
p.setId("Patient/" + methodName);
|
||||||
IdDt id = ourPatientDao.update(p).getId();
|
IIdType id = ourPatientDao.update(p).getId();
|
||||||
ourLog.info("Created patient, got it: {}", id);
|
ourLog.info("Created patient, got it: {}", id);
|
||||||
|
|
||||||
Bundle request = new Bundle();
|
Bundle request = new Bundle();
|
||||||
|
@ -531,14 +520,14 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
p.setId("Patient/" + methodName);
|
p.setId("Patient/" + methodName);
|
||||||
IdDt idv1 = ourPatientDao.update(p).getId();
|
IIdType idv1 = ourPatientDao.update(p).getId();
|
||||||
ourLog.info("Created patient, got id: {}", idv1);
|
ourLog.info("Created patient, got id: {}", idv1);
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
p.addName().addFamily("Family Name");
|
p.addName().addFamily("Family Name");
|
||||||
p.setId("Patient/" + methodName);
|
p.setId("Patient/" + methodName);
|
||||||
IdDt idv2 = ourPatientDao.update(p).getId();
|
IIdType idv2 = ourPatientDao.update(p).getId();
|
||||||
ourLog.info("Updated patient, got id: {}", idv2);
|
ourLog.info("Updated patient, got id: {}", idv2);
|
||||||
|
|
||||||
Bundle request = new Bundle();
|
Bundle request = new Bundle();
|
||||||
|
@ -573,14 +562,14 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
p.setId("Patient/" + methodName);
|
p.setId("Patient/" + methodName);
|
||||||
IdDt idv1 = ourPatientDao.update(p).getId();
|
IIdType idv1 = ourPatientDao.update(p).getId();
|
||||||
ourLog.info("Created patient, got id: {}", idv1);
|
ourLog.info("Created patient, got id: {}", idv1);
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
p.addName().addFamily("Family Name");
|
p.addName().addFamily("Family Name");
|
||||||
p.setId("Patient/" + methodName);
|
p.setId("Patient/" + methodName);
|
||||||
IdDt idv2 = ourPatientDao.update(p).getId();
|
IIdType idv2 = ourPatientDao.update(p).getId();
|
||||||
ourLog.info("Updated patient, got id: {}", idv2);
|
ourLog.info("Updated patient, got id: {}", idv2);
|
||||||
|
|
||||||
Bundle request = new Bundle();
|
Bundle request = new Bundle();
|
||||||
|
@ -619,14 +608,14 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
p.setId("Patient/" + methodName);
|
p.setId("Patient/" + methodName);
|
||||||
IdDt idv1 = ourPatientDao.update(p).getId();
|
IIdType idv1 = ourPatientDao.update(p).getId();
|
||||||
ourLog.info("Created patient, got id: {}", idv1);
|
ourLog.info("Created patient, got id: {}", idv1);
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
p.addName().addFamily("Family Name");
|
p.addName().addFamily("Family Name");
|
||||||
p.setId("Patient/" + methodName);
|
p.setId("Patient/" + methodName);
|
||||||
IdDt idv2 = ourPatientDao.update(p).getId();
|
IIdType idv2 = ourPatientDao.update(p).getId();
|
||||||
ourLog.info("Updated patient, got id: {}", idv2);
|
ourLog.info("Updated patient, got id: {}", idv2);
|
||||||
|
|
||||||
Bundle request = new Bundle();
|
Bundle request = new Bundle();
|
||||||
|
@ -664,7 +653,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
IdDt id = ourPatientDao.create(p).getId();
|
IIdType id = ourPatientDao.create(p).getId();
|
||||||
ourLog.info("Created patient, got it: {}", id);
|
ourLog.info("Created patient, got it: {}", id);
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
|
@ -705,7 +694,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
IdDt id = ourPatientDao.create(p).getId();
|
IIdType id = ourPatientDao.create(p).getId();
|
||||||
ourLog.info("Created patient, got it: {}", id);
|
ourLog.info("Created patient, got it: {}", id);
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
|
@ -739,7 +728,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addName().addFamily("Hello");
|
p.addName().addFamily("Hello");
|
||||||
IdDt id = ourPatientDao.create(p).getId();
|
IIdType id = ourPatientDao.create(p).getId();
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
|
@ -778,7 +767,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||||
p.setId("Patient/" + methodName);
|
p.setId("Patient/" + methodName);
|
||||||
IdDt id = ourPatientDao.update(p).getId();
|
IIdType id = ourPatientDao.update(p).getId();
|
||||||
ourLog.info("Created patient, got it: {}", id);
|
ourLog.info("Created patient, got it: {}", id);
|
||||||
|
|
||||||
p = new Patient();
|
p = new Patient();
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.apache.commons.io.IOUtils;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -111,7 +112,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
|
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testCreateWithId01");
|
p1.addIdentifier().setSystem("urn:system").setValue("testCreateWithId01");
|
||||||
IdDt p1Id = ourClient.create().resource(p1).withId("testCreateWithId").execute().getId();
|
IIdType p1Id = ourClient.create().resource(p1).withId("testCreateWithId").execute().getId();
|
||||||
|
|
||||||
assertThat(p1Id.getValue(), containsString("Patient/testCreateWithId/_history"));
|
assertThat(p1Id.getValue(), containsString("Patient/testCreateWithId/_history"));
|
||||||
|
|
||||||
|
@ -143,12 +144,12 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
|
|
||||||
Location l1 = new Location();
|
Location l1 = new Location();
|
||||||
l1.getNameElement().setValue("testDeepChainingL1");
|
l1.getNameElement().setValue("testDeepChainingL1");
|
||||||
IdDt l1id = ourClient.create().resource(l1).execute().getId();
|
IIdType l1id = ourClient.create().resource(l1).execute().getId();
|
||||||
|
|
||||||
Location l2 = new Location();
|
Location l2 = new Location();
|
||||||
l2.getNameElement().setValue("testDeepChainingL2");
|
l2.getNameElement().setValue("testDeepChainingL2");
|
||||||
l2.getPartOf().setReference(l1id.toVersionless().toUnqualified());
|
l2.getPartOf().setReference(l1id.toVersionless().toUnqualified());
|
||||||
IdDt l2id = ourClient.create().resource(l2).execute().getId();
|
IIdType l2id = ourClient.create().resource(l2).execute().getId();
|
||||||
|
|
||||||
Encounter e1 = new Encounter();
|
Encounter e1 = new Encounter();
|
||||||
e1.addIdentifier().setSystem("urn:foo").setValue("testDeepChainingE1");
|
e1.addIdentifier().setSystem("urn:foo").setValue("testDeepChainingE1");
|
||||||
|
@ -157,7 +158,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
ca.uhn.fhir.model.dstu.resource.Encounter.Location location = e1.addLocation();
|
ca.uhn.fhir.model.dstu.resource.Encounter.Location location = e1.addLocation();
|
||||||
location.getLocation().setReference(l2id.toUnqualifiedVersionless());
|
location.getLocation().setReference(l2id.toUnqualifiedVersionless());
|
||||||
location.setPeriod(new PeriodDt().setStartWithSecondsPrecision(new Date()).setEndWithSecondsPrecision(new Date()));
|
location.setPeriod(new PeriodDt().setStartWithSecondsPrecision(new Date()).setEndWithSecondsPrecision(new Date()));
|
||||||
IdDt e1id = ourClient.create().resource(e1).execute().getId();
|
IIdType e1id = ourClient.create().resource(e1).execute().getId();
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
Bundle res = ourClient.search()
|
Bundle res = ourClient.search()
|
||||||
|
@ -257,9 +258,9 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
p1.getText().getDiv().setValueAsString("<div>HELLO WORLD</div>");
|
p1.getText().getDiv().setValueAsString("<div>HELLO WORLD</div>");
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveExistingNarrative01");
|
p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveExistingNarrative01");
|
||||||
|
|
||||||
IdDt newId = ourClient.create().resource(p1).execute().getId();
|
IIdType newId = ourClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
Patient actual = ourClient.read(Patient.class, newId);
|
Patient actual = ourClient.read(Patient.class, (IdDt)newId);
|
||||||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
|
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,9 +274,9 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
|
|
||||||
p1.getManagingOrganization().setResource(o1);
|
p1.getManagingOrganization().setResource(o1);
|
||||||
|
|
||||||
IdDt newId = ourClient.create().resource(p1).execute().getId();
|
IIdType newId = ourClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
Patient actual = ourClient.read(Patient.class, newId);
|
Patient actual = ourClient.read(Patient.class, (IdDt)newId);
|
||||||
assertEquals(1, actual.getContained().getContainedResources().size());
|
assertEquals(1, actual.getContained().getContainedResources().size());
|
||||||
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSaveAndRetrieveWithContained01</td>"));
|
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSaveAndRetrieveWithContained01</td>"));
|
||||||
|
|
||||||
|
@ -289,9 +290,9 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
|
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
|
||||||
|
|
||||||
IdDt newId = ourClient.create().resource(p1).execute().getId();
|
IIdType newId = ourClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
Patient actual = ourClient.read(Patient.class, newId);
|
Patient actual = ourClient.read(Patient.class, (IdDt)newId);
|
||||||
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSearchByResourceChain01</td>"));
|
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSearchByResourceChain01</td>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +304,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier01");
|
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier01");
|
||||||
p1.addName().addFamily("testSearchByIdentifierFamily01").addGiven("testSearchByIdentifierGiven01");
|
p1.addName().addFamily("testSearchByIdentifierFamily01").addGiven("testSearchByIdentifierGiven01");
|
||||||
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
|
IIdType p1Id = ourClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
Patient p2 = new Patient();
|
Patient p2 = new Patient();
|
||||||
p2.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier02");
|
p2.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier02");
|
||||||
|
@ -321,7 +322,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
|
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01");
|
p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01");
|
||||||
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
|
IIdType p1Id = ourClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode(null, "testSearchByIdentifierWithoutSystem01")).encodedJson().prettyPrint().execute();
|
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode(null, "testSearchByIdentifierWithoutSystem01")).encodedJson().prettyPrint().execute();
|
||||||
assertEquals(1, actual.size());
|
assertEquals(1, actual.size());
|
||||||
|
@ -336,13 +337,13 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
|
|
||||||
Organization o1 = new Organization();
|
Organization o1 = new Organization();
|
||||||
o1.setName("testSearchByResourceChainName01");
|
o1.setName("testSearchByResourceChainName01");
|
||||||
IdDt o1id = ourClient.create().resource(o1).execute().getId();
|
IIdType o1id = ourClient.create().resource(o1).execute().getId();
|
||||||
|
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
|
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
|
||||||
p1.addName().addFamily("testSearchByResourceChainFamily01").addGiven("testSearchByResourceChainGiven01");
|
p1.addName().addFamily("testSearchByResourceChainFamily01").addGiven("testSearchByResourceChainGiven01");
|
||||||
p1.setManagingOrganization(new ResourceReferenceDt(o1id));
|
p1.setManagingOrganization(new ResourceReferenceDt(o1id));
|
||||||
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
|
IIdType p1Id = ourClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
Bundle actual = ourClient.search()
|
Bundle actual = ourClient.search()
|
||||||
|
@ -368,7 +369,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
public void testSearchWithInclude() throws Exception {
|
public void testSearchWithInclude() throws Exception {
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.addIdentifier().setSystem("urn:system").setValue( "testSearchWithInclude01");
|
org.addIdentifier().setSystem("urn:system").setValue( "testSearchWithInclude01");
|
||||||
IdDt orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
|
IIdType orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
|
||||||
|
|
||||||
Patient pat = new Patient();
|
Patient pat = new Patient();
|
||||||
pat.addIdentifier().setSystem("urn:system").setValue("testSearchWithInclude02");
|
pat.addIdentifier().setSystem("urn:system").setValue("testSearchWithInclude02");
|
||||||
|
@ -401,7 +402,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.setName("測試醫院");
|
org.setName("測試醫院");
|
||||||
org.addIdentifier().setSystem("urn:system").setValue("testStoreUtf8Characters_01");
|
org.addIdentifier().setSystem("urn:system").setValue("testStoreUtf8Characters_01");
|
||||||
IdDt orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
|
IIdType orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
|
||||||
|
|
||||||
// Read back directly from the DAO
|
// Read back directly from the DAO
|
||||||
{
|
{
|
||||||
|
@ -412,7 +413,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
}
|
}
|
||||||
// Read back through the HTTP API
|
// Read back through the HTTP API
|
||||||
{
|
{
|
||||||
Organization returned = ourClient.read(Organization.class, orgId);
|
Organization returned = ourClient.read(Organization.class, (IdDt)orgId);
|
||||||
String val = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(returned);
|
String val = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(returned);
|
||||||
ourLog.info(val);
|
ourLog.info(val);
|
||||||
assertThat(val, containsString("<name value=\"測試醫院\"/>"));
|
assertThat(val, containsString("<name value=\"測試醫院\"/>"));
|
||||||
|
@ -444,7 +445,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsInvalidTypes");
|
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsInvalidTypes");
|
||||||
p1.addName().addFamily("Tester").addGiven("testUpdateRejectsInvalidTypes");
|
p1.addName().addFamily("Tester").addGiven("testUpdateRejectsInvalidTypes");
|
||||||
IdDt p1id = ourClient.create().resource(p1).execute().getId();
|
IIdType p1id = ourClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
Organization p2 = new Organization();
|
Organization p2 = new Organization();
|
||||||
p2.getNameElement().setValue("testUpdateRejectsInvalidTypes");
|
p2.getNameElement().setValue("testUpdateRejectsInvalidTypes");
|
||||||
|
@ -472,7 +473,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateWithClientSuppliedIdWhichDoesntExist");
|
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateWithClientSuppliedIdWhichDoesntExist");
|
||||||
MethodOutcome outcome = ourClient.update().resource(p1).withId("testUpdateWithClientSuppliedIdWhichDoesntExist").execute();
|
MethodOutcome outcome = ourClient.update().resource(p1).withId("testUpdateWithClientSuppliedIdWhichDoesntExist").execute();
|
||||||
assertEquals(true, outcome.getCreated().booleanValue());
|
assertEquals(true, outcome.getCreated().booleanValue());
|
||||||
IdDt p1Id = outcome.getId();
|
IIdType p1Id = outcome.getId();
|
||||||
|
|
||||||
assertThat(p1Id.getValue(), containsString("Patient/testUpdateWithClientSuppliedIdWhichDoesntExist/_history"));
|
assertThat(p1Id.getValue(), containsString("Patient/testUpdateWithClientSuppliedIdWhichDoesntExist/_history"));
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
package ca.uhn.fhir.jpa.provider;
|
package ca.uhn.fhir.jpa.provider;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.*;
|
||||||
import static org.hamcrest.Matchers.containsInRelativeOrder;
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.hamcrest.Matchers.greaterThan;
|
|
||||||
import static org.hamcrest.Matchers.hasItems;
|
|
||||||
import static org.hamcrest.Matchers.not;
|
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
@ -38,6 +32,7 @@ import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -77,6 +72,7 @@ import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
import ca.uhn.fhir.model.primitive.UnsignedIntDt;
|
import ca.uhn.fhir.model.primitive.UnsignedIntDt;
|
||||||
|
import ca.uhn.fhir.model.primitive.UriDt;
|
||||||
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
|
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
|
||||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||||
|
@ -141,7 +137,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
IGenericClient client = ourClient;
|
IGenericClient client = ourClient;
|
||||||
|
|
||||||
String resBody = IOUtils.toString(ResourceProviderDstu2Test.class.getResource("/document-father.json"));
|
String resBody = IOUtils.toString(ResourceProviderDstu2Test.class.getResource("/document-father.json"));
|
||||||
IdDt id = client.create().resource(resBody).execute().getId();
|
IIdType id = client.create().resource(resBody).execute().getId();
|
||||||
|
|
||||||
ourLog.info("Created: {}", id);
|
ourLog.info("Created: {}", id);
|
||||||
|
|
||||||
|
@ -246,12 +242,12 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
Location l1 = new Location();
|
Location l1 = new Location();
|
||||||
l1.getNameElement().setValue("testDeepChainingL1");
|
l1.getNameElement().setValue("testDeepChainingL1");
|
||||||
IdDt l1id = ourClient.create().resource(l1).execute().getId();
|
IIdType l1id = ourClient.create().resource(l1).execute().getId();
|
||||||
|
|
||||||
Location l2 = new Location();
|
Location l2 = new Location();
|
||||||
l2.getNameElement().setValue("testDeepChainingL2");
|
l2.getNameElement().setValue("testDeepChainingL2");
|
||||||
l2.getPartOf().setReference(l1id.toVersionless().toUnqualified());
|
l2.getPartOf().setReference(l1id.toVersionless().toUnqualified());
|
||||||
IdDt l2id = ourClient.create().resource(l2).execute().getId();
|
IIdType l2id = ourClient.create().resource(l2).execute().getId();
|
||||||
|
|
||||||
Encounter e1 = new Encounter();
|
Encounter e1 = new Encounter();
|
||||||
e1.addIdentifier().setSystem("urn:foo").setValue("testDeepChainingE1");
|
e1.addIdentifier().setSystem("urn:foo").setValue("testDeepChainingE1");
|
||||||
|
@ -260,7 +256,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
ca.uhn.fhir.model.dstu2.resource.Encounter.Location location = e1.addLocation();
|
ca.uhn.fhir.model.dstu2.resource.Encounter.Location location = e1.addLocation();
|
||||||
location.getLocation().setReference(l2id.toUnqualifiedVersionless());
|
location.getLocation().setReference(l2id.toUnqualifiedVersionless());
|
||||||
location.setPeriod(new PeriodDt().setStartWithSecondsPrecision(new Date()).setEndWithSecondsPrecision(new Date()));
|
location.setPeriod(new PeriodDt().setStartWithSecondsPrecision(new Date()).setEndWithSecondsPrecision(new Date()));
|
||||||
IdDt e1id = ourClient.create().resource(e1).execute().getId();
|
IIdType e1id = ourClient.create().resource(e1).execute().getId();
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
Bundle res = ourClient.search()
|
Bundle res = ourClient.search()
|
||||||
|
@ -542,30 +538,30 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
Organization org1 = new Organization();
|
Organization org1 = new Organization();
|
||||||
org1.setName(methodName + "1");
|
org1.setName(methodName + "1");
|
||||||
IdDt orgId1 = ourClient.create().resource(org1).execute().getId();
|
IIdType orgId1 = ourClient.create().resource(org1).execute().getId();
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addName().addFamily(methodName);
|
p.addName().addFamily(methodName);
|
||||||
p.getManagingOrganization().setReference(orgId1);
|
p.getManagingOrganization().setReference(orgId1);
|
||||||
IdDt patientId = ourClient.create().resource(p).execute().getId();
|
IIdType patientId = ourClient.create().resource(p).execute().getId();
|
||||||
|
|
||||||
Organization org2 = new Organization();
|
Organization org2 = new Organization();
|
||||||
org2.setName(methodName + "1");
|
org2.setName(methodName + "1");
|
||||||
IdDt orgId2 = ourClient.create().resource(org2).execute().getId();
|
IIdType orgId2 = ourClient.create().resource(org2).execute().getId();
|
||||||
|
|
||||||
Device dev = new Device();
|
Device dev = new Device();
|
||||||
dev.setModel(methodName);
|
dev.setModel(methodName);
|
||||||
dev.getOwner().setReference(orgId2);
|
dev.getOwner().setReference(orgId2);
|
||||||
IdDt devId = ourClient.create().resource(dev).execute().getId();
|
IIdType devId = ourClient.create().resource(dev).execute().getId();
|
||||||
|
|
||||||
Observation obs = new Observation();
|
Observation obs = new Observation();
|
||||||
obs.getSubject().setReference(patientId);
|
obs.getSubject().setReference(patientId);
|
||||||
obs.getDevice().setReference(devId);
|
obs.getDevice().setReference(devId);
|
||||||
IdDt obsId = ourClient.create().resource(obs).execute().getId();
|
IIdType obsId = ourClient.create().resource(obs).execute().getId();
|
||||||
|
|
||||||
Encounter enc = new Encounter();
|
Encounter enc = new Encounter();
|
||||||
enc.getPatient().setReference(patientId);
|
enc.getPatient().setReference(patientId);
|
||||||
IdDt encId = ourClient.create().resource(enc).execute().getId();
|
IIdType encId = ourClient.create().resource(enc).execute().getId();
|
||||||
|
|
||||||
Parameters output = ourClient.operation().onInstance(patientId).named("everything").withNoParameters(Parameters.class).execute();
|
Parameters output = ourClient.operation().onInstance(patientId).named("everything").withNoParameters(Parameters.class).execute();
|
||||||
ca.uhn.fhir.model.dstu2.resource.Bundle b = (ca.uhn.fhir.model.dstu2.resource.Bundle) output.getParameterFirstRep().getResource();
|
ca.uhn.fhir.model.dstu2.resource.Bundle b = (ca.uhn.fhir.model.dstu2.resource.Bundle) output.getParameterFirstRep().getResource();
|
||||||
|
@ -636,9 +632,9 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
p1.getText().getDiv().setValueAsString("<div>HELLO WORLD</div>");
|
p1.getText().getDiv().setValueAsString("<div>HELLO WORLD</div>");
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveExistingNarrative01");
|
p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveExistingNarrative01");
|
||||||
|
|
||||||
IdDt newId = ourClient.create().resource(p1).execute().getId();
|
IIdType newId = ourClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
Patient actual = ourClient.read(Patient.class, newId);
|
Patient actual = ourClient.read(Patient.class, (UriDt)newId);
|
||||||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
|
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,9 +648,9 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
p1.getManagingOrganization().setResource(o1);
|
p1.getManagingOrganization().setResource(o1);
|
||||||
|
|
||||||
IdDt newId = ourClient.create().resource(p1).execute().getId();
|
IIdType newId = ourClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
Patient actual = ourClient.read(Patient.class, newId);
|
Patient actual = ourClient.read(Patient.class, (UriDt)newId);
|
||||||
assertEquals(1, actual.getContained().getContainedResources().size());
|
assertEquals(1, actual.getContained().getContainedResources().size());
|
||||||
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSaveAndRetrieveWithContained01</td>"));
|
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSaveAndRetrieveWithContained01</td>"));
|
||||||
|
|
||||||
|
@ -668,7 +664,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
|
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
|
||||||
|
|
||||||
IdDt newId = ourClient.create().resource(p1).execute().getId();
|
IdDt newId = (IdDt) ourClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
Patient actual = ourClient.read(Patient.class, newId);
|
Patient actual = ourClient.read(Patient.class, newId);
|
||||||
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSearchByResourceChain01</td>"));
|
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSearchByResourceChain01</td>"));
|
||||||
|
@ -696,7 +692,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier01");
|
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier01");
|
||||||
p1.addName().addFamily("testSearchByIdentifierFamily01").addGiven("testSearchByIdentifierGiven01");
|
p1.addName().addFamily("testSearchByIdentifierFamily01").addGiven("testSearchByIdentifierGiven01");
|
||||||
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
|
IdDt p1Id = (IdDt) ourClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
Patient p2 = new Patient();
|
Patient p2 = new Patient();
|
||||||
p2.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier02");
|
p2.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier02");
|
||||||
|
@ -715,7 +711,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01");
|
p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01");
|
||||||
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
|
IdDt p1Id = (IdDt) ourClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode(null, "testSearchByIdentifierWithoutSystem01")).encodedJson().prettyPrint()
|
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode(null, "testSearchByIdentifierWithoutSystem01")).encodedJson().prettyPrint()
|
||||||
.execute();
|
.execute();
|
||||||
|
@ -731,13 +727,13 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
|
|
||||||
Organization o1 = new Organization();
|
Organization o1 = new Organization();
|
||||||
o1.setName("testSearchByResourceChainName01");
|
o1.setName("testSearchByResourceChainName01");
|
||||||
IdDt o1id = ourClient.create().resource(o1).execute().getId();
|
IdDt o1id = (IdDt) ourClient.create().resource(o1).execute().getId();
|
||||||
|
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
|
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
|
||||||
p1.addName().addFamily("testSearchByResourceChainFamily01").addGiven("testSearchByResourceChainGiven01");
|
p1.addName().addFamily("testSearchByResourceChainFamily01").addGiven("testSearchByResourceChainGiven01");
|
||||||
p1.setManagingOrganization(new ResourceReferenceDt(o1id));
|
p1.setManagingOrganization(new ResourceReferenceDt(o1id));
|
||||||
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
|
IdDt p1Id = (IdDt) ourClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
Bundle actual = ourClient.search()
|
Bundle actual = ourClient.search()
|
||||||
|
@ -763,7 +759,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
public void testSearchWithInclude() throws Exception {
|
public void testSearchWithInclude() throws Exception {
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.addIdentifier().setSystem("urn:system:rpdstu2").setValue("testSearchWithInclude01");
|
org.addIdentifier().setSystem("urn:system:rpdstu2").setValue("testSearchWithInclude01");
|
||||||
IdDt orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
|
IdDt orgId = (IdDt) ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
|
||||||
|
|
||||||
Patient pat = new Patient();
|
Patient pat = new Patient();
|
||||||
pat.addIdentifier().setSystem("urn:system:rpdstu2").setValue("testSearchWithInclude02");
|
pat.addIdentifier().setSystem("urn:system:rpdstu2").setValue("testSearchWithInclude02");
|
||||||
|
@ -827,12 +823,12 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
String methodName = "testSearchWithMissing";
|
String methodName = "testSearchWithMissing";
|
||||||
|
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
IdDt deletedIdMissingTrue = ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless();
|
IdDt deletedIdMissingTrue = (IdDt) ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless();
|
||||||
ourClient.delete().resourceById(deletedIdMissingTrue).execute();
|
ourClient.delete().resourceById(deletedIdMissingTrue).execute();
|
||||||
|
|
||||||
org = new Organization();
|
org = new Organization();
|
||||||
org.setName("Help I'm a Bug");
|
org.setName("Help I'm a Bug");
|
||||||
IdDt deletedIdMissingFalse = ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless();
|
IdDt deletedIdMissingFalse = (IdDt) ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless();
|
||||||
ourClient.delete().resourceById(deletedIdMissingFalse).execute();
|
ourClient.delete().resourceById(deletedIdMissingFalse).execute();
|
||||||
|
|
||||||
List<IResource> resources = new ArrayList<IResource>();
|
List<IResource> resources = new ArrayList<IResource>();
|
||||||
|
@ -846,11 +842,11 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
org = new Organization();
|
org = new Organization();
|
||||||
org.addIdentifier().setSystem("urn:system:rpdstu2").setValue(methodName + "01");
|
org.addIdentifier().setSystem("urn:system:rpdstu2").setValue(methodName + "01");
|
||||||
org.setName(methodName + "name");
|
org.setName(methodName + "name");
|
||||||
IdDt orgNotMissing = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId().toUnqualifiedVersionless();
|
IdDt orgNotMissing = (IdDt) ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
org = new Organization();
|
org = new Organization();
|
||||||
org.addIdentifier().setSystem("urn:system:rpdstu2").setValue(methodName + "01");
|
org.addIdentifier().setSystem("urn:system:rpdstu2").setValue(methodName + "01");
|
||||||
IdDt orgMissing = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId().toUnqualifiedVersionless();
|
IdDt orgMissing = (IdDt) ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
{
|
{
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
@ -896,7 +892,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
Organization org = new Organization();
|
Organization org = new Organization();
|
||||||
org.setName("測試醫院");
|
org.setName("測試醫院");
|
||||||
org.addIdentifier().setSystem("urn:system").setValue("testStoreUtf8Characters_01");
|
org.addIdentifier().setSystem("urn:system").setValue("testStoreUtf8Characters_01");
|
||||||
IdDt orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
|
IdDt orgId = (IdDt) ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
|
||||||
|
|
||||||
// Read back directly from the DAO
|
// Read back directly from the DAO
|
||||||
{
|
{
|
||||||
|
@ -939,7 +935,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsInvalidTypes");
|
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsInvalidTypes");
|
||||||
p1.addName().addFamily("Tester").addGiven("testUpdateRejectsInvalidTypes");
|
p1.addName().addFamily("Tester").addGiven("testUpdateRejectsInvalidTypes");
|
||||||
IdDt p1id = ourClient.create().resource(p1).execute().getId();
|
IdDt p1id = (IdDt) ourClient.create().resource(p1).execute().getId();
|
||||||
|
|
||||||
Organization p2 = new Organization();
|
Organization p2 = new Organization();
|
||||||
p2.getNameElement().setValue("testUpdateRejectsInvalidTypes");
|
p2.getNameElement().setValue("testUpdateRejectsInvalidTypes");
|
||||||
|
@ -1002,7 +998,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2");
|
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2");
|
||||||
MethodOutcome outcome = ourClient.update().resource(p1).withId("testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2").execute();
|
MethodOutcome outcome = ourClient.update().resource(p1).withId("testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2").execute();
|
||||||
assertEquals(true, outcome.getCreated().booleanValue());
|
assertEquals(true, outcome.getCreated().booleanValue());
|
||||||
IdDt p1Id = outcome.getId();
|
IdDt p1Id = (IdDt) outcome.getId();
|
||||||
|
|
||||||
assertThat(p1Id.getValue(), containsString("Patient/testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2/_history"));
|
assertThat(p1Id.getValue(), containsString("Patient/testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2/_history"));
|
||||||
|
|
||||||
|
@ -1040,6 +1036,33 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateResourceWithId() throws IOException {
|
||||||
|
|
||||||
|
Patient patient = new Patient();
|
||||||
|
patient.addName().addGiven("James");
|
||||||
|
patient.setBirthDate(new DateDt("2011-02-02"));
|
||||||
|
|
||||||
|
Parameters input = new Parameters();
|
||||||
|
input.addParameter().setName("resource").setResource(patient);
|
||||||
|
|
||||||
|
String inputStr = ourCtx.newXmlParser().encodeResourceToString(input);
|
||||||
|
ourLog.info(inputStr);
|
||||||
|
|
||||||
|
HttpPost post = new HttpPost(ourServerBase + "/Patient/123/$validate");
|
||||||
|
post.setEntity(new StringEntity(inputStr, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||||
|
|
||||||
|
CloseableHttpResponse response = ourHttpClient.execute(post);
|
||||||
|
try {
|
||||||
|
String resp = IOUtils.toString(response.getEntity().getContent());
|
||||||
|
ourLog.info(resp);
|
||||||
|
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(response.getEntity().getContent());
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidateResourceHuge() throws IOException {
|
public void testValidateResourceHuge() throws IOException {
|
||||||
|
|
||||||
|
@ -1148,14 +1171,14 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||||
patient.addName().addFamily(methodName).addGiven("Joe");
|
patient.addName().addFamily(methodName).addGiven("Joe");
|
||||||
id1a = ourClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
|
id1a = (IdDt) ourClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
|
||||||
}
|
}
|
||||||
IdDt id1b;
|
IdDt id1b;
|
||||||
{
|
{
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||||
patient.addName().addFamily(methodName + "XXXX").addGiven("Joe");
|
patient.addName().addFamily(methodName + "XXXX").addGiven("Joe");
|
||||||
id1b = ourClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
|
id1b = (IdDt) ourClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread.sleep(1100);
|
Thread.sleep(1100);
|
||||||
|
@ -1167,7 +1190,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||||
patient.addName().addFamily(methodName).addGiven("John");
|
patient.addName().addFamily(methodName).addGiven("John");
|
||||||
id2 = ourClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
|
id2 = (IdDt) ourClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class ResourceProviderMultiVersionTest extends BaseJpaTest {
|
||||||
p.addIdentifier("urn:MultiFhirVersionTest", "testSubmitPatient01");
|
p.addIdentifier("urn:MultiFhirVersionTest", "testSubmitPatient01");
|
||||||
p.addUndeclaredExtension(false, "http://foo#ext1", new StringDt("The value"));
|
p.addUndeclaredExtension(false, "http://foo#ext1", new StringDt("The value"));
|
||||||
p.getGender().setValueAsEnum(AdministrativeGenderCodesEnum.M);
|
p.getGender().setValueAsEnum(AdministrativeGenderCodesEnum.M);
|
||||||
IdDt id = ourClientDstu1.create().resource(p).execute().getId();
|
IdDt id = (IdDt) ourClientDstu1.create().resource(p).execute().getId();
|
||||||
|
|
||||||
// Read back as DSTU1
|
// Read back as DSTU1
|
||||||
Patient patDstu1 = ourClientDstu1.read(Patient.class, id);
|
Patient patDstu1 = ourClientDstu1.read(Patient.class, id);
|
||||||
|
@ -76,7 +76,7 @@ public class ResourceProviderMultiVersionTest extends BaseJpaTest {
|
||||||
p.addIdentifier().setSystem("urn:MultiFhirVersionTest").setValue("testSubmitPatientDstu201");
|
p.addIdentifier().setSystem("urn:MultiFhirVersionTest").setValue("testSubmitPatientDstu201");
|
||||||
p.addUndeclaredExtension(false, "http://foo#ext1", new StringDt("The value"));
|
p.addUndeclaredExtension(false, "http://foo#ext1", new StringDt("The value"));
|
||||||
p.setGender(AdministrativeGenderEnum.MALE);
|
p.setGender(AdministrativeGenderEnum.MALE);
|
||||||
IdDt id = ourClientDstu2.create().resource(p).execute().getId();
|
IdDt id = (IdDt) ourClientDstu2.create().resource(p).execute().getId();
|
||||||
|
|
||||||
// Read back as DSTU1
|
// Read back as DSTU1
|
||||||
Patient patDstu1 = ourClientDstu1.read(Patient.class, id);
|
Patient patDstu1 = ourClientDstu1.read(Patient.class, id);
|
||||||
|
@ -105,7 +105,7 @@ public class ResourceProviderMultiVersionTest extends BaseJpaTest {
|
||||||
public void testUnknownResourceType() {
|
public void testUnknownResourceType() {
|
||||||
ca.uhn.fhir.model.dstu2.resource.Patient p = new ca.uhn.fhir.model.dstu2.resource.Patient();
|
ca.uhn.fhir.model.dstu2.resource.Patient p = new ca.uhn.fhir.model.dstu2.resource.Patient();
|
||||||
p.addIdentifier().setSystem("urn:MultiFhirVersionTest").setValue("testUnknownResourceType01");
|
p.addIdentifier().setSystem("urn:MultiFhirVersionTest").setValue("testUnknownResourceType01");
|
||||||
IdDt id = ourClientDstu2.create().resource(p).execute().getId();
|
IdDt id = (IdDt) ourClientDstu2.create().resource(p).execute().getId();
|
||||||
|
|
||||||
PaymentNotice s = new PaymentNotice();
|
PaymentNotice s = new PaymentNotice();
|
||||||
s.addIdentifier().setSystem("urn:MultiFhirVersionTest").setValue("testUnknownResourceType02");
|
s.addIdentifier().setSystem("urn:MultiFhirVersionTest").setValue("testUnknownResourceType02");
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class UhnFhirTestApp {
|
||||||
Organization o1 = new Organization();
|
Organization o1 = new Organization();
|
||||||
o1.getName().setValue("Some Org");
|
o1.getName().setValue("Some Org");
|
||||||
MethodOutcome create = client.create(o1);
|
MethodOutcome create = client.create(o1);
|
||||||
IdDt orgId = create.getId();
|
IdDt orgId = (IdDt) create.getId();
|
||||||
|
|
||||||
Patient p1 = new Patient();
|
Patient p1 = new Patient();
|
||||||
p1.addIdentifier("foo:bar", "12345");
|
p1.addIdentifier("foo:bar", "12345");
|
||||||
|
|
|
@ -25,6 +25,7 @@ import static org.apache.commons.lang3.StringUtils.*;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
@ -34,6 +35,7 @@ import java.util.Map;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.text.WordUtils;
|
import org.apache.commons.lang3.text.WordUtils;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeDeclaredChildDefinition;
|
import ca.uhn.fhir.context.BaseRuntimeDeclaredChildDefinition;
|
||||||
|
@ -60,6 +62,7 @@ import ca.uhn.fhir.model.api.ICompositeDatatype;
|
||||||
import ca.uhn.fhir.model.api.IFhirVersion;
|
import ca.uhn.fhir.model.api.IFhirVersion;
|
||||||
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
import ca.uhn.fhir.model.api.annotation.Child;
|
import ca.uhn.fhir.model.api.annotation.Child;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
|
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
|
||||||
|
@ -85,7 +88,8 @@ import ca.uhn.fhir.rest.server.provider.ServerProfileProvider;
|
||||||
public class FhirDstu1 implements IFhirVersion {
|
public class FhirDstu1 implements IFhirVersion {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirDstu1.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirDstu1.class);
|
||||||
// private Map<RuntimeChildDeclaredExtensionDefinition, String> myExtensionDefToCode = new HashMap<RuntimeChildDeclaredExtensionDefinition, String>();
|
// private Map<RuntimeChildDeclaredExtensionDefinition, String> myExtensionDefToCode = new
|
||||||
|
// HashMap<RuntimeChildDeclaredExtensionDefinition, String>();
|
||||||
private String myId;
|
private String myId;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -93,6 +97,11 @@ public class FhirDstu1 implements IFhirVersion {
|
||||||
return new ServerConformanceProvider(theServer);
|
return new ServerConformanceProvider(theServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IResourceProvider createServerProfilesProvider(RestfulServer theRestfulServer) {
|
||||||
|
return new ServerProfileProvider(theRestfulServer);
|
||||||
|
}
|
||||||
|
|
||||||
private void fillBasics(StructureElement theElement, BaseRuntimeElementDefinition<?> def, LinkedList<String> path, BaseRuntimeDeclaredChildDefinition theChild) {
|
private void fillBasics(StructureElement theElement, BaseRuntimeElementDefinition<?> def, LinkedList<String> path, BaseRuntimeDeclaredChildDefinition theChild) {
|
||||||
if (path.isEmpty()) {
|
if (path.isEmpty()) {
|
||||||
path.add(def.getName());
|
path.add(def.getName());
|
||||||
|
@ -234,8 +243,7 @@ public class FhirDstu1 implements IFhirVersion {
|
||||||
// ignore
|
// ignore
|
||||||
} else if (child instanceof RuntimeChildDeclaredExtensionDefinition) {
|
} else if (child instanceof RuntimeChildDeclaredExtensionDefinition) {
|
||||||
throw new IllegalStateException("Unexpected child type: " + child.getClass().getCanonicalName());
|
throw new IllegalStateException("Unexpected child type: " + child.getClass().getCanonicalName());
|
||||||
} else if (child instanceof RuntimeChildCompositeDatatypeDefinition || child instanceof RuntimeChildPrimitiveDatatypeDefinition || child instanceof RuntimeChildChoiceDefinition
|
} else if (child instanceof RuntimeChildCompositeDatatypeDefinition || child instanceof RuntimeChildPrimitiveDatatypeDefinition || child instanceof RuntimeChildChoiceDefinition || child instanceof RuntimeChildResourceDefinition) {
|
||||||
|| child instanceof RuntimeChildResourceDefinition) {
|
|
||||||
Iterator<String> childNamesIter = child.getValidChildNames().iterator();
|
Iterator<String> childNamesIter = child.getValidChildNames().iterator();
|
||||||
String nextName = childNamesIter.next();
|
String nextName = childNamesIter.next();
|
||||||
BaseRuntimeElementDefinition<?> nextDef = child.getChildByName(nextName);
|
BaseRuntimeElementDefinition<?> nextDef = child.getChildByName(nextName);
|
||||||
|
@ -295,6 +303,53 @@ public class FhirDstu1 implements IFhirVersion {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends BaseContainedDt> getContainedType() {
|
||||||
|
return ContainedDt.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getFhirVersionPropertiesFile() {
|
||||||
|
InputStream str = FhirDstu1.class.getResourceAsStream("/ca/uhn/fhir/model/dstu/fhirversion.properties");
|
||||||
|
if (str == null) {
|
||||||
|
str = FhirDstu1.class.getResourceAsStream("ca/uhn/fhir/model/dstu/fhirversion.properties");
|
||||||
|
}
|
||||||
|
if (str == null) {
|
||||||
|
throw new ConfigurationException("Can not find model property file on classpath: " + "/ca/uhn/fhir/model/dstu/model.properties");
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPrimitiveType<Date> getLastUpdated(IBaseResource theResource) {
|
||||||
|
return ResourceMetadataKeyEnum.UPDATED.get((IResource) theResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPathToSchemaDefinitions() {
|
||||||
|
return "/ca/uhn/fhir/model/dstu/schema";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends BaseResourceReferenceDt> getResourceReferenceType() {
|
||||||
|
return ResourceReferenceDt.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FhirVersionEnum getVersion() {
|
||||||
|
return FhirVersionEnum.DSTU1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IVersionSpecificBundleFactory newBundleFactory(FhirContext theContext) {
|
||||||
|
return new Dstu1BundleFactory(theContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseCodingDt newCodingDt() {
|
||||||
|
return new CodingDt();
|
||||||
|
}
|
||||||
|
|
||||||
private Map<RuntimeChildDeclaredExtensionDefinition, String> scanForExtensions(Profile theProfile, BaseRuntimeElementDefinition<?> def, Map<RuntimeChildDeclaredExtensionDefinition, String> theExtensionDefToCode) {
|
private Map<RuntimeChildDeclaredExtensionDefinition, String> scanForExtensions(Profile theProfile, BaseRuntimeElementDefinition<?> def, Map<RuntimeChildDeclaredExtensionDefinition, String> theExtensionDefToCode) {
|
||||||
BaseRuntimeElementCompositeDefinition<?> cdef = ((BaseRuntimeElementCompositeDefinition<?>) def);
|
BaseRuntimeElementCompositeDefinition<?> cdef = ((BaseRuntimeElementCompositeDefinition<?>) def);
|
||||||
|
|
||||||
|
@ -339,57 +394,8 @@ public class FhirDstu1 implements IFhirVersion {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return theExtensionDefToCode;
|
return theExtensionDefToCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IResourceProvider createServerProfilesProvider(RestfulServer theRestfulServer) {
|
|
||||||
return new ServerProfileProvider(theRestfulServer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FhirVersionEnum getVersion() {
|
|
||||||
return FhirVersionEnum.DSTU1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getFhirVersionPropertiesFile() {
|
|
||||||
InputStream str = FhirDstu1.class.getResourceAsStream("/ca/uhn/fhir/model/dstu/fhirversion.properties");
|
|
||||||
if (str == null) {
|
|
||||||
str = FhirDstu1.class.getResourceAsStream("ca/uhn/fhir/model/dstu/fhirversion.properties");
|
|
||||||
}
|
|
||||||
if (str == null) {
|
|
||||||
throw new ConfigurationException("Can not find model property file on classpath: " + "/ca/uhn/fhir/model/dstu/model.properties");
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPathToSchemaDefinitions() {
|
|
||||||
return "ca/uhn/fhir/model/dstu/schema";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<? extends BaseResourceReferenceDt> getResourceReferenceType() {
|
|
||||||
return ResourceReferenceDt.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<? extends BaseContainedDt> getContainedType() {
|
|
||||||
return ContainedDt.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BaseCodingDt newCodingDt() {
|
|
||||||
return new CodingDt();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IVersionSpecificBundleFactory newBundleFactory(FhirContext theContext) {
|
|
||||||
return new Dstu1BundleFactory(theContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ package ca.uhn.fhir.model.dstu.composite;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.ICompositeDatatype;
|
import ca.uhn.fhir.model.api.ICompositeDatatype;
|
||||||
import ca.uhn.fhir.model.api.IElement;
|
import ca.uhn.fhir.model.api.IElement;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
@ -110,7 +112,7 @@ public class ResourceReferenceDt
|
||||||
* @param theResourceId
|
* @param theResourceId
|
||||||
* The reference itself
|
* The reference itself
|
||||||
*/
|
*/
|
||||||
public ResourceReferenceDt(IdDt theResourceId) {
|
public ResourceReferenceDt(IIdType theResourceId) {
|
||||||
setReference(theResourceId);
|
setReference(theResourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -245,7 +245,7 @@ public class ClientDstu1Test {
|
||||||
|
|
||||||
assertEquals(HttpDelete.class, capt.getValue().getClass());
|
assertEquals(HttpDelete.class, capt.getValue().getClass());
|
||||||
assertEquals("http://foo/Patient/1234", capt.getValue().getURI().toString());
|
assertEquals("http://foo/Patient/1234", capt.getValue().getURI().toString());
|
||||||
assertEquals("Hello", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
|
assertEquals("Hello", ((OperationOutcome)response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -1155,7 +1155,7 @@ public class RestfulServerMethodTest {
|
||||||
public MethodOutcome deletePatient(@IdParam IdDt theId) {
|
public MethodOutcome deletePatient(@IdParam IdDt theId) {
|
||||||
MethodOutcome retVal = new MethodOutcome();
|
MethodOutcome retVal = new MethodOutcome();
|
||||||
retVal.setOperationOutcome(new OperationOutcome());
|
retVal.setOperationOutcome(new OperationOutcome());
|
||||||
retVal.getOperationOutcome().addIssue().setDetails(theId.getValue());
|
((OperationOutcome)retVal.getOperationOutcome()).addIssue().setDetails(theId.getValue());
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,17 @@
|
||||||
package ca.uhn.fhir.validation;
|
package ca.uhn.fhir.validation;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.hamcrest.core.StringContains;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.Bundle;
|
import ca.uhn.fhir.model.api.Bundle;
|
||||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||||
|
@ -7,23 +19,6 @@ import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.ContactSystemEnum;
|
import ca.uhn.fhir.model.dstu.valueset.ContactSystemEnum;
|
||||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.hamcrest.core.StringContains;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
public class ResourceValidatorTest {
|
public class ResourceValidatorTest {
|
||||||
|
|
||||||
private static FhirContext ourCtx = FhirContext.forDstu1();
|
private static FhirContext ourCtx = FhirContext.forDstu1();
|
||||||
|
@ -46,9 +41,10 @@ public class ResourceValidatorTest {
|
||||||
val.validate(p);
|
val.validate(p);
|
||||||
fail();
|
fail();
|
||||||
} catch (ValidationFailureException e) {
|
} catch (ValidationFailureException e) {
|
||||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
|
OperationOutcome outcome = (OperationOutcome) e.getOperationOutcome();
|
||||||
assertEquals(1, e.getOperationOutcome().getIssue().size());
|
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
||||||
assertThat(e.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue(), containsString("cvc-complex-type.2.4.a"));
|
assertEquals(1, outcome.getIssue().size());
|
||||||
|
assertThat(outcome.getIssueFirstRep().getDetailsElement().getValue(), containsString("cvc-complex-type.2.4.a"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +87,7 @@ public class ResourceValidatorTest {
|
||||||
String resultString = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.getOperationOutcome());
|
String resultString = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.getOperationOutcome());
|
||||||
ourLog.info(resultString);
|
ourLog.info(resultString);
|
||||||
|
|
||||||
assertEquals(2, result.getOperationOutcome().getIssue().size());
|
assertEquals(2, ((OperationOutcome)result.getOperationOutcome()).getIssue().size());
|
||||||
assertThat(resultString, StringContains.containsString("cvc-datatype-valid.1.2.3"));
|
assertThat(resultString, StringContains.containsString("cvc-datatype-valid.1.2.3"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,9 +107,10 @@ public class ResourceValidatorTest {
|
||||||
val.validate(b);
|
val.validate(b);
|
||||||
fail();
|
fail();
|
||||||
} catch (ValidationFailureException e) {
|
} catch (ValidationFailureException e) {
|
||||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
|
OperationOutcome outcome = (OperationOutcome) e.getOperationOutcome();
|
||||||
assertEquals(1, e.getOperationOutcome().getIssue().size());
|
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(outcome));
|
||||||
assertThat(e.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue(), containsString("Inv-2:"));
|
assertEquals(1, outcome.getIssue().size());
|
||||||
|
assertThat(outcome.getIssueFirstRep().getDetailsElement().getValue(), containsString("Inv-2:"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package ca.uhn.fhir.validation;
|
package ca.uhn.fhir.validation;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
|
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
|
||||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -15,46 +17,48 @@ import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class ValidationResultDstu1Test {
|
public class ValidationResultDstu1Test {
|
||||||
|
|
||||||
@Test
|
private static final FhirContext ourCtx = FhirContext.forDstu1();
|
||||||
public void isSuccessful_IsTrueForNullOperationOutcome() {
|
|
||||||
ValidationResult result = ValidationResult.valueOf(null);
|
|
||||||
assertTrue(result.isSuccessful());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void isSuccessful_IsTrueForNoIssues() {
|
public void isSuccessful_FalseForIssues() {
|
||||||
OperationOutcome operationOutcome = new OperationOutcome();
|
OperationOutcome operationOutcome = new OperationOutcome();
|
||||||
// make sure a non-null ID doesn't cause the validation result to be a fail
|
OperationOutcome.Issue issue = operationOutcome.addIssue();
|
||||||
operationOutcome.setId(UUID.randomUUID().toString());
|
String errorMessage = "There was a validation problem";
|
||||||
ValidationResult result = ValidationResult.valueOf(operationOutcome);
|
issue.setDetails(errorMessage);
|
||||||
assertTrue(result.isSuccessful());
|
ValidationResult result = ValidationResult.valueOf(ourCtx, operationOutcome);
|
||||||
}
|
assertFalse(result.isSuccessful());
|
||||||
|
List<? extends BaseIssue> issues = ((OperationOutcome) result.getOperationOutcome()).getIssue();
|
||||||
|
assertEquals(1, issues.size());
|
||||||
|
assertEquals(errorMessage, issues.get(0).getDetailsElement().getValue());
|
||||||
|
|
||||||
@Test
|
assertThat("ValidationResult#toString should contain the issue description", result.toString(), containsString(errorMessage));
|
||||||
public void isSuccessful_FalseForIssues() {
|
}
|
||||||
OperationOutcome operationOutcome = new OperationOutcome();
|
|
||||||
OperationOutcome.Issue issue = operationOutcome.addIssue();
|
|
||||||
String errorMessage = "There was a validation problem";
|
|
||||||
issue.setDetails(errorMessage);
|
|
||||||
ValidationResult result = ValidationResult.valueOf(operationOutcome);
|
|
||||||
assertFalse(result.isSuccessful());
|
|
||||||
List<? extends BaseIssue> issues = result.getOperationOutcome().getIssue();
|
|
||||||
assertEquals(1, issues.size());
|
|
||||||
assertEquals(errorMessage, issues.get(0).getDetailsElement().getValue());
|
|
||||||
|
|
||||||
assertThat("ValidationResult#toString should contain the issue description", result.toString(), containsString(errorMessage));
|
@Test
|
||||||
}
|
public void isSuccessful_IsTrueForNoIssues() {
|
||||||
|
OperationOutcome operationOutcome = new OperationOutcome();
|
||||||
|
// make sure a non-null ID doesn't cause the validation result to be a fail
|
||||||
|
operationOutcome.setId(UUID.randomUUID().toString());
|
||||||
|
ValidationResult result = ValidationResult.valueOf(ourCtx, operationOutcome);
|
||||||
|
assertTrue(result.isSuccessful());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
@Test
|
||||||
Test for https://github.com/jamesagnew/hapi-fhir/issues/51
|
public void isSuccessful_IsTrueForNullOperationOutcome() {
|
||||||
*/
|
ValidationResult result = ValidationResult.valueOf(ourCtx, null);
|
||||||
@Test
|
assertTrue(result.isSuccessful());
|
||||||
public void toString_ShouldNotCauseResultToBecomeFailure() {
|
}
|
||||||
OperationOutcome operationOutcome = new OperationOutcome();
|
|
||||||
ValidationResult result = ValidationResult.valueOf(operationOutcome);
|
/*
|
||||||
assertEquals(true, result.isSuccessful());
|
* Test for https://github.com/jamesagnew/hapi-fhir/issues/51
|
||||||
// need to call toString to make sure any unwanted side effects are generated
|
*/
|
||||||
@SuppressWarnings("UnusedDeclaration") String unused = result.toString();
|
@Test
|
||||||
assertEquals(true, result.isSuccessful());
|
public void toString_ShouldNotCauseResultToBecomeFailure() {
|
||||||
}
|
OperationOutcome operationOutcome = new OperationOutcome();
|
||||||
|
ValidationResult result = ValidationResult.valueOf(ourCtx, operationOutcome);
|
||||||
|
assertEquals(true, result.isSuccessful());
|
||||||
|
// need to call toString to make sure any unwanted side effects are generated
|
||||||
|
result.toString();
|
||||||
|
assertEquals(true, result.isSuccessful());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,11 @@ package ca.uhn.fhir.model.dstu2;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
@ -30,6 +33,7 @@ import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.model.api.IFhirVersion;
|
import ca.uhn.fhir.model.api.IFhirVersion;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
|
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
||||||
|
@ -54,6 +58,11 @@ public class FhirDstu2 implements IFhirVersion {
|
||||||
return new ServerConformanceProvider(theServer);
|
return new ServerConformanceProvider(theServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IResourceProvider createServerProfilesProvider(RestfulServer theRestfulServer) {
|
||||||
|
return new ServerProfileProvider(theRestfulServer);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IResource generateProfile(RuntimeResourceDefinition theRuntimeResourceDefinition, String theServerBase) {
|
public IResource generateProfile(RuntimeResourceDefinition theRuntimeResourceDefinition, String theServerBase) {
|
||||||
StructureDefinition retVal = new StructureDefinition();
|
StructureDefinition retVal = new StructureDefinition();
|
||||||
|
@ -70,13 +79,8 @@ public class FhirDstu2 implements IFhirVersion {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IResourceProvider createServerProfilesProvider(RestfulServer theRestfulServer) {
|
public Class<? extends BaseContainedDt> getContainedType() {
|
||||||
return new ServerProfileProvider(theRestfulServer);
|
return ContainedDt.class;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FhirVersionEnum getVersion() {
|
|
||||||
return FhirVersionEnum.DSTU2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -91,9 +95,14 @@ public class FhirDstu2 implements IFhirVersion {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPrimitiveType<Date> getLastUpdated(IBaseResource theResource) {
|
||||||
|
return ResourceMetadataKeyEnum.UPDATED.get((IResource) theResource);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPathToSchemaDefinitions() {
|
public String getPathToSchemaDefinitions() {
|
||||||
return "ca/uhn/fhir/model/dstu2/schema";
|
return "/ca/uhn/fhir/model/dstu2/schema";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -102,13 +111,8 @@ public class FhirDstu2 implements IFhirVersion {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<? extends BaseContainedDt> getContainedType() {
|
public FhirVersionEnum getVersion() {
|
||||||
return ContainedDt.class;
|
return FhirVersionEnum.DSTU2;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BaseCodingDt newCodingDt() {
|
|
||||||
return new CodingDt();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -116,5 +120,9 @@ public class FhirDstu2 implements IFhirVersion {
|
||||||
return new Dstu2BundleFactory(theContext);
|
return new Dstu2BundleFactory(theContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseCodingDt newCodingDt() {
|
||||||
|
return new CodingDt();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ package ca.uhn.fhir.model.dstu2.composite;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.ICompositeDatatype;
|
import ca.uhn.fhir.model.api.ICompositeDatatype;
|
||||||
import ca.uhn.fhir.model.api.IElement;
|
import ca.uhn.fhir.model.api.IElement;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
@ -114,6 +116,17 @@ public class ResourceReferenceDt
|
||||||
setReference(theResourceId);
|
setReference(theResourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor which accepts a reference directly (this can be an ID, a partial/relative URL or a complete/absolute
|
||||||
|
* URL)
|
||||||
|
*
|
||||||
|
* @param theResourceId
|
||||||
|
* The reference itself
|
||||||
|
*/
|
||||||
|
public ResourceReferenceDt(IIdType theResourceId) {
|
||||||
|
setReference(theResourceId);
|
||||||
|
}
|
||||||
|
|
||||||
@Child(name="reference", type=IdDt.class, order=0, min=0, max=1)
|
@Child(name="reference", type=IdDt.class, order=0, min=0, max=1)
|
||||||
@Description(
|
@Description(
|
||||||
shortDefinition="Relative, internal or absolute URL reference",
|
shortDefinition="Relative, internal or absolute URL reference",
|
||||||
|
|
|
@ -24,23 +24,22 @@ import static org.apache.commons.lang3.StringUtils.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.Include;
|
|
||||||
import ca.uhn.fhir.rest.server.*;
|
|
||||||
import ca.uhn.fhir.util.ResourceReferenceInfo;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.Validate;
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
|
import ca.uhn.fhir.model.api.Include;
|
||||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
|
||||||
|
@ -53,7 +52,17 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
|
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
|
||||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||||
|
import ca.uhn.fhir.rest.server.AddProfileTagEnum;
|
||||||
|
import ca.uhn.fhir.rest.server.BundleInclusionRule;
|
||||||
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
|
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||||
|
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||||
|
import ca.uhn.fhir.rest.server.IPagingProvider;
|
||||||
|
import ca.uhn.fhir.rest.server.IVersionSpecificBundleFactory;
|
||||||
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
|
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
import ca.uhn.fhir.util.ResourceReferenceInfo;
|
||||||
|
|
||||||
public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
||||||
|
|
||||||
|
@ -159,14 +168,14 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, InstantDt theLastUpdated) {
|
public void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, IPrimitiveType<Date> theLastUpdated) {
|
||||||
|
|
||||||
if (myBundle.getId().isEmpty()) {
|
if (myBundle.getId().isEmpty()) {
|
||||||
myBundle.setId(UUID.randomUUID().toString());
|
myBundle.setId(UUID.randomUUID().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ResourceMetadataKeyEnum.UPDATED.get(myBundle) == null) {
|
if (ResourceMetadataKeyEnum.UPDATED.get(myBundle) == null) {
|
||||||
ResourceMetadataKeyEnum.UPDATED.put(myBundle, theLastUpdated);
|
ResourceMetadataKeyEnum.UPDATED.put(myBundle, (InstantDt) theLastUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasLink(Constants.LINK_SELF, myBundle) && isNotBlank(theCompleteUrl)) {
|
if (!hasLink(Constants.LINK_SELF, myBundle) && isNotBlank(theCompleteUrl)) {
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.apache.http.client.methods.HttpUriRequest;
|
||||||
import org.apache.http.message.BasicHeader;
|
import org.apache.http.message.BasicHeader;
|
||||||
import org.apache.http.message.BasicStatusLine;
|
import org.apache.http.message.BasicStatusLine;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
@ -1174,10 +1175,14 @@ public class GenericClientDstu2Test {
|
||||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
|
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
|
||||||
assertNotNull(response.getOperationOutcome());
|
assertNotNull(response.getOperationOutcome());
|
||||||
assertEquals("FOOBAR", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
|
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private OperationOutcome toOo(IBaseOperationOutcome theOperationOutcome) {
|
||||||
|
return (OperationOutcome) theOperationOutcome;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidateFluent() throws Exception {
|
public void testValidateFluent() throws Exception {
|
||||||
|
|
||||||
|
@ -1209,7 +1214,7 @@ public class GenericClientDstu2Test {
|
||||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
|
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
|
||||||
assertNotNull(response.getOperationOutcome());
|
assertNotNull(response.getOperationOutcome());
|
||||||
assertEquals("FOOBAR", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
|
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
response = client.validate().resource(ourCtx.newXmlParser().encodeResourceToString(p)).execute();
|
response = client.validate().resource(ourCtx.newXmlParser().encodeResourceToString(p)).execute();
|
||||||
|
@ -1217,7 +1222,7 @@ public class GenericClientDstu2Test {
|
||||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||||
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
|
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
|
||||||
assertNotNull(response.getOperationOutcome());
|
assertNotNull(response.getOperationOutcome());
|
||||||
assertEquals("FOOBAR", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
|
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
response = client.validate().resource(ourCtx.newJsonParser().encodeResourceToString(p)).execute();
|
response = client.validate().resource(ourCtx.newJsonParser().encodeResourceToString(p)).execute();
|
||||||
|
@ -1225,7 +1230,7 @@ public class GenericClientDstu2Test {
|
||||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||||
assertEquals("{\"resourceType\":\"Parameters\",\"parameter\":[{\"name\":\"resource\",\"resource\":{\"resourceType\":\"Patient\",\"name\":[{\"given\":[\"GIVEN\"]}]}}]}", extractBody(capt, idx));
|
assertEquals("{\"resourceType\":\"Parameters\",\"parameter\":[{\"name\":\"resource\",\"resource\":{\"resourceType\":\"Patient\",\"name\":[{\"given\":[\"GIVEN\"]}]}}]}", extractBody(capt, idx));
|
||||||
assertNotNull(response.getOperationOutcome());
|
assertNotNull(response.getOperationOutcome());
|
||||||
assertEquals("FOOBAR", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
|
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
response = client.validate().resource(ourCtx.newJsonParser().encodeResourceToString(p)).prettyPrint().execute();
|
response = client.validate().resource(ourCtx.newJsonParser().encodeResourceToString(p)).prettyPrint().execute();
|
||||||
|
@ -1233,7 +1238,7 @@ public class GenericClientDstu2Test {
|
||||||
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
|
||||||
assertThat(extractBody(capt, idx), containsString("\"resourceType\":\"Parameters\",\n"));
|
assertThat(extractBody(capt, idx), containsString("\"resourceType\":\"Parameters\",\n"));
|
||||||
assertNotNull(response.getOperationOutcome());
|
assertNotNull(response.getOperationOutcome());
|
||||||
assertEquals("FOOBAR", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
|
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,13 +43,13 @@ import ca.uhn.fhir.util.PortUtil;
|
||||||
/**
|
/**
|
||||||
* Created by dsotnikov on 2/25/2014.
|
* Created by dsotnikov on 2/25/2014.
|
||||||
*/
|
*/
|
||||||
public class BinaryTestDstu2 {
|
public class BinaryDstu2Test {
|
||||||
|
|
||||||
private static CloseableHttpClient ourClient;
|
private static CloseableHttpClient ourClient;
|
||||||
private static FhirContext ourCtx = FhirContext.forDstu2();
|
private static FhirContext ourCtx = FhirContext.forDstu2();
|
||||||
private static Binary ourLast;
|
private static Binary ourLast;
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BinaryTestDstu2.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BinaryDstu2Test.class);
|
||||||
|
|
||||||
private static int ourPort;
|
private static int ourPort;
|
||||||
|
|
|
@ -235,11 +235,13 @@ public class IncludeDstu2Test {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTwoInclude() throws Exception {
|
public void testTwoInclude() throws Exception {
|
||||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello&_include=foo&_include=bar");
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello&_include=foo&_include=bar&_pretty=true");
|
||||||
HttpResponse status = ourClient.execute(httpGet);
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
|
||||||
|
ourLog.info(responseContent);
|
||||||
|
|
||||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
|
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
|
||||||
assertEquals(1, bundle.size());
|
assertEquals(1, bundle.size());
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.util.Locale;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.hamcrest.core.StringContains;
|
import org.hamcrest.core.StringContains;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
@ -65,7 +66,7 @@ public class ResourceValidatorDstu2Test {
|
||||||
String resultString = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.getOperationOutcome());
|
String resultString = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.getOperationOutcome());
|
||||||
ourLog.info(resultString);
|
ourLog.info(resultString);
|
||||||
|
|
||||||
assertEquals(2, result.getOperationOutcome().getIssue().size());
|
assertEquals(2, ((OperationOutcome)result.getOperationOutcome()).getIssue().size());
|
||||||
assertThat(resultString, StringContains.containsString("2000-15-31"));
|
assertThat(resultString, StringContains.containsString("2000-15-31"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,9 +157,10 @@ public class ResourceValidatorDstu2Test {
|
||||||
val.validate(p);
|
val.validate(p);
|
||||||
fail();
|
fail();
|
||||||
} catch (ValidationFailureException e) {
|
} catch (ValidationFailureException e) {
|
||||||
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
|
OperationOutcome operationOutcome = (OperationOutcome) e.getOperationOutcome();
|
||||||
assertEquals(1, e.getOperationOutcome().getIssue().size());
|
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome));
|
||||||
assertThat(e.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue(), containsString("cvc-complex-type"));
|
assertEquals(1, operationOutcome.getIssue().size());
|
||||||
|
assertThat(operationOutcome.getIssueFirstRep().getDetailsElement().getValue(), containsString("cvc-complex-type"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,14 +11,17 @@ import java.util.UUID;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
|
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
||||||
|
|
||||||
public class ValidationResultDstu2Test {
|
public class ValidationResultDstu2Test {
|
||||||
|
|
||||||
|
private static final FhirContext ourCtx = FhirContext.forDstu2();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void isSuccessful_IsTrueForNullOperationOutcome() {
|
public void isSuccessful_IsTrueForNullOperationOutcome() {
|
||||||
ValidationResult result = ValidationResult.valueOf(null);
|
ValidationResult result = ValidationResult.valueOf(ourCtx, null);
|
||||||
assertTrue(result.isSuccessful());
|
assertTrue(result.isSuccessful());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +30,7 @@ public class ValidationResultDstu2Test {
|
||||||
OperationOutcome operationOutcome = new OperationOutcome();
|
OperationOutcome operationOutcome = new OperationOutcome();
|
||||||
// make sure a non-null ID doesn't cause the validation result to be a fail
|
// make sure a non-null ID doesn't cause the validation result to be a fail
|
||||||
operationOutcome.setId(UUID.randomUUID().toString());
|
operationOutcome.setId(UUID.randomUUID().toString());
|
||||||
ValidationResult result = ValidationResult.valueOf(operationOutcome);
|
ValidationResult result = ValidationResult.valueOf(ourCtx, operationOutcome);
|
||||||
assertTrue(result.isSuccessful());
|
assertTrue(result.isSuccessful());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,9 +40,9 @@ public class ValidationResultDstu2Test {
|
||||||
OperationOutcome.Issue issue = operationOutcome.addIssue();
|
OperationOutcome.Issue issue = operationOutcome.addIssue();
|
||||||
String errorMessage = "There was a validation problem";
|
String errorMessage = "There was a validation problem";
|
||||||
issue.setDetails(errorMessage);
|
issue.setDetails(errorMessage);
|
||||||
ValidationResult result = ValidationResult.valueOf(operationOutcome);
|
ValidationResult result = ValidationResult.valueOf(ourCtx, operationOutcome);
|
||||||
assertFalse(result.isSuccessful());
|
assertFalse(result.isSuccessful());
|
||||||
List<? extends BaseIssue> issues = result.getOperationOutcome().getIssue();
|
List<? extends BaseIssue> issues = ((OperationOutcome)result.getOperationOutcome()).getIssue();
|
||||||
assertEquals(1, issues.size());
|
assertEquals(1, issues.size());
|
||||||
assertEquals(errorMessage, issues.get(0).getDetailsElement().getValue());
|
assertEquals(errorMessage, issues.get(0).getDetailsElement().getValue());
|
||||||
|
|
||||||
|
@ -52,7 +55,7 @@ public class ValidationResultDstu2Test {
|
||||||
@Test
|
@Test
|
||||||
public void toString_ShouldNotCauseResultToBecomeFailure() {
|
public void toString_ShouldNotCauseResultToBecomeFailure() {
|
||||||
OperationOutcome operationOutcome = new OperationOutcome();
|
OperationOutcome operationOutcome = new OperationOutcome();
|
||||||
ValidationResult result = ValidationResult.valueOf(operationOutcome);
|
ValidationResult result = ValidationResult.valueOf(ourCtx, operationOutcome);
|
||||||
assertEquals(true, result.isSuccessful());
|
assertEquals(true, result.isSuccessful());
|
||||||
// need to call toString to make sure any unwanted side effects are generated
|
// need to call toString to make sure any unwanted side effects are generated
|
||||||
@SuppressWarnings("UnusedDeclaration") String unused = result.toString();
|
@SuppressWarnings("UnusedDeclaration") String unused = result.toString();
|
||||||
|
|
|
@ -23,6 +23,8 @@ package ca.uhn.fhir.rest.server.provider.dstu2hl7org;
|
||||||
import static org.apache.commons.lang3.StringUtils.*;
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -43,11 +45,11 @@ import org.hl7.fhir.instance.model.api.IBaseReference;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.IDomainResource;
|
import org.hl7.fhir.instance.model.api.IDomainResource;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.model.api.Include;
|
import ca.uhn.fhir.model.api.Include;
|
||||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
|
||||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||||
import ca.uhn.fhir.rest.server.AddProfileTagEnum;
|
import ca.uhn.fhir.rest.server.AddProfileTagEnum;
|
||||||
import ca.uhn.fhir.rest.server.BundleInclusionRule;
|
import ca.uhn.fhir.rest.server.BundleInclusionRule;
|
||||||
|
@ -85,14 +87,18 @@ public class Dstu2Hl7OrgBundleFactory implements IVersionSpecificBundleFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IBaseResource nextBaseRes : theResult) {
|
for (IBaseResource next : theResult) {
|
||||||
if (!(nextBaseRes instanceof IDomainResource)) {
|
|
||||||
continue;
|
List<? extends IAnyResource> contained;
|
||||||
|
if (next instanceof IDomainResource) {
|
||||||
|
IDomainResource nextDomain = (IDomainResource) next;
|
||||||
|
contained = nextDomain.getContained();
|
||||||
|
} else {
|
||||||
|
contained = Collections.emptyList();
|
||||||
}
|
}
|
||||||
IDomainResource next = (IDomainResource) nextBaseRes;
|
|
||||||
|
|
||||||
Set<String> containedIds = new HashSet<String>();
|
Set<String> containedIds = new HashSet<String>();
|
||||||
for (IAnyResource nextContained : next.getContained()) {
|
for (IAnyResource nextContained : contained) {
|
||||||
if (nextContained.getId().isEmpty() == false) {
|
if (nextContained.getId().isEmpty() == false) {
|
||||||
containedIds.add(nextContained.getIdElement().getValue());
|
containedIds.add(nextContained.getIdElement().getValue());
|
||||||
}
|
}
|
||||||
|
@ -157,9 +163,9 @@ public class Dstu2Hl7OrgBundleFactory implements IVersionSpecificBundleFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, InstantDt theLastUpdated) {
|
public void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, IPrimitiveType<Date> theLastUpdated) {
|
||||||
|
|
||||||
if (myBundle.getId().isEmpty()) {
|
if (isBlank(myBundle.getId())) {
|
||||||
myBundle.setId(UUID.randomUUID().toString());
|
myBundle.setId(UUID.randomUUID().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,9 +209,12 @@ public class Dstu2Hl7OrgBundleFactory implements IVersionSpecificBundleFactory {
|
||||||
List<IBaseResource> resourceList;
|
List<IBaseResource> resourceList;
|
||||||
if (theServer.getPagingProvider() == null) {
|
if (theServer.getPagingProvider() == null) {
|
||||||
numToReturn = theResult.size();
|
numToReturn = theResult.size();
|
||||||
resourceList = theResult.getResources(0, numToReturn);
|
if (numToReturn == 0) {
|
||||||
RestfulServerUtils.validateResourceListNotNull(resourceList);
|
resourceList = Collections.emptyList();
|
||||||
|
} else {
|
||||||
|
resourceList = theResult.getResources(0, numToReturn);
|
||||||
|
RestfulServerUtils.validateResourceListNotNull(resourceList);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
IPagingProvider pagingProvider = theServer.getPagingProvider();
|
IPagingProvider pagingProvider = theServer.getPagingProvider();
|
||||||
if (theLimit == null) {
|
if (theLimit == null) {
|
||||||
|
|
|
@ -22,12 +22,16 @@ package org.hl7.fhir.instance;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.hl7.fhir.instance.conf.ServerConformanceProvider;
|
import org.hl7.fhir.instance.conf.ServerConformanceProvider;
|
||||||
import org.hl7.fhir.instance.conf.ServerProfileProvider;
|
import org.hl7.fhir.instance.conf.ServerProfileProvider;
|
||||||
import org.hl7.fhir.instance.model.Reference;
|
import org.hl7.fhir.instance.model.Reference;
|
||||||
|
import org.hl7.fhir.instance.model.Resource;
|
||||||
import org.hl7.fhir.instance.model.StructureDefinition;
|
import org.hl7.fhir.instance.model.StructureDefinition;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
@ -89,7 +93,7 @@ public class FhirDstu2Hl7Org implements IFhirVersion {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPathToSchemaDefinitions() {
|
public String getPathToSchemaDefinitions() {
|
||||||
return "ca/uhn/fhir/model/dstu2/schema";
|
return "/org/hl7/fhir/instance/model/schema";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -113,4 +117,9 @@ public class FhirDstu2Hl7Org implements IFhirVersion {
|
||||||
return new Dstu2Hl7OrgBundleFactory(theContext);
|
return new Dstu2Hl7OrgBundleFactory(theContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPrimitiveType<Date> getLastUpdated(IBaseResource theResource) {
|
||||||
|
return ((Resource)theResource).getMeta().getLastUpdatedElement();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package org.hl7.fhir.instance.conf;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR Structures - HL7.org DSTU2
|
* HAPI FHIR Structures - DSTU2 (FHIR v0.5.0)
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2014 - 2015 University Health Network
|
* Copyright (C) 2014 - 2015 University Health Network
|
||||||
* %%
|
* %%
|
||||||
|
@ -20,12 +20,18 @@ package org.hl7.fhir.instance.conf;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -39,18 +45,20 @@ import org.hl7.fhir.instance.model.Conformance.ResourceInteractionComponent;
|
||||||
import org.hl7.fhir.instance.model.Conformance.RestfulConformanceMode;
|
import org.hl7.fhir.instance.model.Conformance.RestfulConformanceMode;
|
||||||
import org.hl7.fhir.instance.model.Conformance.SystemRestfulInteraction;
|
import org.hl7.fhir.instance.model.Conformance.SystemRestfulInteraction;
|
||||||
import org.hl7.fhir.instance.model.Conformance.TypeRestfulInteraction;
|
import org.hl7.fhir.instance.model.Conformance.TypeRestfulInteraction;
|
||||||
import org.hl7.fhir.instance.model.DateTimeType;
|
import org.hl7.fhir.instance.model.Enumerations.ConformanceResourceStatus;
|
||||||
import org.hl7.fhir.instance.model.ResourceType;
|
import org.hl7.fhir.instance.model.OperationDefinition;
|
||||||
|
import org.hl7.fhir.instance.model.OperationDefinition.OperationDefinitionParameterComponent;
|
||||||
|
import org.hl7.fhir.instance.model.OperationDefinition.OperationParameterUse;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
|
||||||
import ca.uhn.fhir.rest.annotation.Metadata;
|
import ca.uhn.fhir.rest.annotation.Metadata;
|
||||||
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
||||||
import ca.uhn.fhir.rest.method.DynamicSearchMethodBinding;
|
import ca.uhn.fhir.rest.method.DynamicSearchMethodBinding;
|
||||||
import ca.uhn.fhir.rest.method.IParameter;
|
import ca.uhn.fhir.rest.method.IParameter;
|
||||||
|
import ca.uhn.fhir.rest.method.OperationMethodBinding;
|
||||||
|
import ca.uhn.fhir.rest.method.OperationParameter;
|
||||||
import ca.uhn.fhir.rest.method.SearchMethodBinding;
|
import ca.uhn.fhir.rest.method.SearchMethodBinding;
|
||||||
import ca.uhn.fhir.rest.method.SearchParameter;
|
import ca.uhn.fhir.rest.method.SearchParameter;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
|
@ -63,8 +71,10 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
* Server FHIR Provider which serves the conformance statement for a RESTful server implementation
|
* Server FHIR Provider which serves the conformance statement for a RESTful server implementation
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Note: This class is safe to extend, but it is important to note that the same instance of {@link Conformance} is always returned unless {@link #setCache(boolean)} is called with a value of
|
* Note: This class is safe to extend, but it is important to note that the same instance of {@link Conformance} is
|
||||||
* <code>false</code>. This means that if you are adding anything to the returned conformance instance on each call you should call <code>setCache(false)</code> in your provider constructor.
|
* always returned unless {@link #setCache(boolean)} is called with a value of <code>false</code>. This means that if
|
||||||
|
* you are adding anything to the returned conformance instance on each call you should call
|
||||||
|
* <code>setCache(false)</code> in your provider constructor.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class ServerConformanceProvider implements IServerConformanceProvider<Conformance> {
|
public class ServerConformanceProvider implements IServerConformanceProvider<Conformance> {
|
||||||
|
@ -79,8 +89,9 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the value of the "publisher" that will be placed in the generated conformance statement. As this is a mandatory element, the value should not be null (although this is not enforced). The
|
* Gets the value of the "publisher" that will be placed in the generated conformance statement. As this is a
|
||||||
* value defaults to "Not provided" but may be set to null, which will cause this element to be omitted.
|
* mandatory element, the value should not be null (although this is not enforced). The value defaults to
|
||||||
|
* "Not provided" but may be set to null, which will cause this element to be omitted.
|
||||||
*/
|
*/
|
||||||
public String getPublisher() {
|
public String getPublisher() {
|
||||||
return myPublisher;
|
return myPublisher;
|
||||||
|
@ -96,10 +107,10 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
|
||||||
Conformance retVal = new Conformance();
|
Conformance retVal = new Conformance();
|
||||||
|
|
||||||
retVal.setPublisher(myPublisher);
|
retVal.setPublisher(myPublisher);
|
||||||
retVal.setDateElement(DateTimeType.now());
|
retVal.setDate(new Date());
|
||||||
retVal.setFhirVersion("0.5.0"); // TODO: pull from model
|
retVal.setFhirVersion("0.5.0"); // TODO: pull from model
|
||||||
retVal.setAcceptUnknown(false); // TODO: make this configurable - this is a fairly big effort since the parser
|
retVal.setAcceptUnknown(false); // TODO: make this configurable - this is a fairly big effort since the parser
|
||||||
// needs to be modified to actually allow it
|
// needs to be modified to actually allow it
|
||||||
|
|
||||||
retVal.getImplementation().setDescription(myRestfulServer.getImplementationDescription());
|
retVal.getImplementation().setDescription(myRestfulServer.getImplementationDescription());
|
||||||
retVal.getSoftware().setName(myRestfulServer.getServerName());
|
retVal.getSoftware().setName(myRestfulServer.getServerName());
|
||||||
|
@ -112,103 +123,167 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
|
||||||
|
|
||||||
Set<SystemRestfulInteraction> systemOps = new HashSet<SystemRestfulInteraction>();
|
Set<SystemRestfulInteraction> systemOps = new HashSet<SystemRestfulInteraction>();
|
||||||
|
|
||||||
List<ResourceBinding> bindings = new ArrayList<ResourceBinding>(myRestfulServer.getResourceBindings());
|
Map<String, List<BaseMethodBinding<?>>> resourceToMethods = new TreeMap<String, List<BaseMethodBinding<?>>>();
|
||||||
Collections.sort(bindings, new Comparator<ResourceBinding>() {
|
for (ResourceBinding next : myRestfulServer.getResourceBindings()) {
|
||||||
@Override
|
|
||||||
public int compare(ResourceBinding theArg0, ResourceBinding theArg1) {
|
|
||||||
return theArg0.getResourceName().compareToIgnoreCase(theArg1.getResourceName());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
for (ResourceBinding next : bindings) {
|
|
||||||
|
|
||||||
Set<TypeRestfulInteraction> resourceOps = new HashSet<TypeRestfulInteraction>();
|
|
||||||
ConformanceRestResourceComponent resource = rest.addResource();
|
|
||||||
|
|
||||||
String resourceName = next.getResourceName();
|
String resourceName = next.getResourceName();
|
||||||
RuntimeResourceDefinition def = myRestfulServer.getFhirContext().getResourceDefinition(resourceName);
|
|
||||||
resource.getTypeElement().setValue(def.getName());
|
|
||||||
resource.getProfile().setReference(def.getResourceProfile(myRestfulServer.getServerBaseForRequest(theRequest)));
|
|
||||||
|
|
||||||
TreeSet<String> includes = new TreeSet<String>();
|
|
||||||
|
|
||||||
// Map<String, Conformance.RestResourceSearchParam> nameToSearchParam = new HashMap<String,
|
|
||||||
// Conformance.RestResourceSearchParam>();
|
|
||||||
for (BaseMethodBinding<?> nextMethodBinding : next.getMethodBindings()) {
|
for (BaseMethodBinding<?> nextMethodBinding : next.getMethodBindings()) {
|
||||||
if (nextMethodBinding.getResourceOperationType() != null) {
|
if (resourceToMethods.containsKey(resourceName) == false) {
|
||||||
String resOpCode = nextMethodBinding.getResourceOperationType().getCode();
|
resourceToMethods.put(resourceName, new ArrayList<BaseMethodBinding<?>>());
|
||||||
if (resOpCode != null) {
|
|
||||||
TypeRestfulInteraction resOp;
|
|
||||||
try {
|
|
||||||
resOp = TypeRestfulInteraction.fromCode(resOpCode);
|
|
||||||
} catch (Exception e) {
|
|
||||||
resOp = null;
|
|
||||||
}
|
|
||||||
if (resOp == null) {
|
|
||||||
throw new InternalErrorException("Unknown type-restful-interaction: " + resOpCode);
|
|
||||||
}
|
|
||||||
if (resourceOps.contains(resOp) == false) {
|
|
||||||
resourceOps.add(resOp);
|
|
||||||
resource.addInteraction().setCode(resOp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
resourceToMethods.get(resourceName).add(nextMethodBinding);
|
||||||
if (nextMethodBinding.getSystemOperationType() != null) {
|
|
||||||
String sysOpCode = nextMethodBinding.getSystemOperationType().getCode();
|
|
||||||
if (sysOpCode != null) {
|
|
||||||
SystemRestfulInteraction sysOp;
|
|
||||||
try {
|
|
||||||
sysOp = SystemRestfulInteraction.fromCode(sysOpCode);
|
|
||||||
} catch (Exception e) {
|
|
||||||
sysOp = null;
|
|
||||||
}
|
|
||||||
if (sysOp == null) {
|
|
||||||
throw new InternalErrorException("Unknown system-restful-interaction: " + sysOpCode);
|
|
||||||
}
|
|
||||||
if (systemOps.contains(sysOp) == false) {
|
|
||||||
systemOps.add(sysOp);
|
|
||||||
rest.addInteraction().setCode(sysOp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextMethodBinding instanceof SearchMethodBinding) {
|
|
||||||
handleSearchMethodBinding(rest, resource, resourceName, def, includes, (SearchMethodBinding) nextMethodBinding);
|
|
||||||
} else if (nextMethodBinding instanceof DynamicSearchMethodBinding) {
|
|
||||||
handleDynamicSearchMethodBinding(resource, def, includes, (DynamicSearchMethodBinding) nextMethodBinding);
|
|
||||||
}
|
|
||||||
|
|
||||||
Collections.sort(resource.getInteraction(), new Comparator<ResourceInteractionComponent>() {
|
|
||||||
@Override
|
|
||||||
public int compare(ResourceInteractionComponent theO1, ResourceInteractionComponent theO2) {
|
|
||||||
TypeRestfulInteraction o1 = theO1.getCodeElement().getValue();
|
|
||||||
TypeRestfulInteraction o2 = theO2.getCodeElement().getValue();
|
|
||||||
if (o1 == null && o2 == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (o1 == null) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (o2 == null) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return o1.ordinal() - o2.ordinal();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for (String nextInclude : includes) {
|
for (BaseMethodBinding<?> nextMethodBinding : myRestfulServer.getServerBindings()) {
|
||||||
resource.addSearchInclude(nextInclude);
|
String resourceName = "";
|
||||||
|
if (resourceToMethods.containsKey(resourceName) == false) {
|
||||||
|
resourceToMethods.put(resourceName, new ArrayList<BaseMethodBinding<?>>());
|
||||||
}
|
}
|
||||||
|
resourceToMethods.get(resourceName).add(nextMethodBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Entry<String, List<BaseMethodBinding<?>>> nextEntry : resourceToMethods.entrySet()) {
|
||||||
|
|
||||||
|
if (nextEntry.getKey().isEmpty() == false) {
|
||||||
|
Set<TypeRestfulInteraction> resourceOps = new HashSet<TypeRestfulInteraction>();
|
||||||
|
ConformanceRestResourceComponent resource = rest.addResource();
|
||||||
|
String resourceName = nextEntry.getKey();
|
||||||
|
RuntimeResourceDefinition def = myRestfulServer.getFhirContext().getResourceDefinition(resourceName);
|
||||||
|
resource.getTypeElement().setValue(def.getName());
|
||||||
|
resource.getProfile().setReference(def.getResourceProfile(myRestfulServer.getServerBaseForRequest(theRequest)));
|
||||||
|
|
||||||
|
TreeSet<String> includes = new TreeSet<String>();
|
||||||
|
|
||||||
|
// Map<String, Conformance.RestResourceSearchParam> nameToSearchParam = new HashMap<String,
|
||||||
|
// Conformance.RestResourceSearchParam>();
|
||||||
|
for (BaseMethodBinding<?> nextMethodBinding : nextEntry.getValue()) {
|
||||||
|
if (nextMethodBinding.getResourceOperationType() != null) {
|
||||||
|
String resOpCode = nextMethodBinding.getResourceOperationType().getCode();
|
||||||
|
if (resOpCode != null) {
|
||||||
|
TypeRestfulInteraction resOp;
|
||||||
|
try {
|
||||||
|
resOp = TypeRestfulInteraction.fromCode(resOpCode);
|
||||||
|
assert resOp != null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InternalErrorException("Unknown type-restful-interaction: " + resOpCode);
|
||||||
|
}
|
||||||
|
if (resourceOps.contains(resOp) == false) {
|
||||||
|
resourceOps.add(resOp);
|
||||||
|
resource.addInteraction().setCode(resOp);
|
||||||
|
}
|
||||||
|
if ("vread".equals(resOpCode)) {
|
||||||
|
// vread implies read
|
||||||
|
resOp = TypeRestfulInteraction.READ;
|
||||||
|
if (resourceOps.contains(resOp) == false) {
|
||||||
|
resourceOps.add(resOp);
|
||||||
|
resource.addInteraction().setCode(resOp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextMethodBinding.isSupportsConditional()) {
|
||||||
|
switch (resOp) {
|
||||||
|
case CREATE:
|
||||||
|
resource.setConditionalCreate(true);
|
||||||
|
break;
|
||||||
|
case DELETE:
|
||||||
|
resource.setConditionalDelete(true);
|
||||||
|
break;
|
||||||
|
case UPDATE:
|
||||||
|
resource.setConditionalUpdate(true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkBindingForSystemOps(rest, systemOps, nextMethodBinding);
|
||||||
|
|
||||||
|
if (nextMethodBinding instanceof SearchMethodBinding) {
|
||||||
|
handleSearchMethodBinding(rest, resource, resourceName, def, includes, (SearchMethodBinding) nextMethodBinding);
|
||||||
|
} else if (nextMethodBinding instanceof DynamicSearchMethodBinding) {
|
||||||
|
handleDynamicSearchMethodBinding(resource, def, includes, (DynamicSearchMethodBinding) nextMethodBinding);
|
||||||
|
} else if (nextMethodBinding instanceof OperationMethodBinding) {
|
||||||
|
OperationMethodBinding methodBinding = (OperationMethodBinding) nextMethodBinding;
|
||||||
|
OperationDefinition op = new OperationDefinition();
|
||||||
|
rest.addOperation().setName(methodBinding.getName()).getDefinition().setResource(op);
|
||||||
|
;
|
||||||
|
|
||||||
|
op.setStatus(ConformanceResourceStatus.ACTIVE);
|
||||||
|
op.setDescription(methodBinding.getDescription());
|
||||||
|
op.setIdempotent(methodBinding.isIdempotent());
|
||||||
|
op.setCode(methodBinding.getName());
|
||||||
|
op.setInstance(methodBinding.isInstanceLevel());
|
||||||
|
op.addType(methodBinding.getResourceName());
|
||||||
|
|
||||||
|
for (IParameter nextParamUntyped : methodBinding.getParameters()) {
|
||||||
|
if (nextParamUntyped instanceof OperationParameter) {
|
||||||
|
OperationParameter nextParam = (OperationParameter) nextParamUntyped;
|
||||||
|
OperationDefinitionParameterComponent param = op.addParameter();
|
||||||
|
param.setUse(OperationParameterUse.IN);
|
||||||
|
if (nextParam.getParamType() != null) {
|
||||||
|
param.setType(nextParam.getParamType().getCode());
|
||||||
|
}
|
||||||
|
param.setMin(nextParam.getMin());
|
||||||
|
param.setMax(nextParam.getMax() == -1 ? "*" : Integer.toString(nextParam.getMax()));
|
||||||
|
param.setName(nextParam.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(resource.getInteraction(), new Comparator<ResourceInteractionComponent>() {
|
||||||
|
@Override
|
||||||
|
public int compare(ResourceInteractionComponent theO1, ResourceInteractionComponent theO2) {
|
||||||
|
TypeRestfulInteraction o1 = theO1.getCode();
|
||||||
|
TypeRestfulInteraction o2 = theO2.getCode();
|
||||||
|
if (o1 == null && o2 == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (o1 == null) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (o2 == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return o1.ordinal() - o2.ordinal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String nextInclude : includes) {
|
||||||
|
resource.addSearchInclude(nextInclude);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (BaseMethodBinding<?> nextMethodBinding : nextEntry.getValue()) {
|
||||||
|
checkBindingForSystemOps(rest, systemOps, nextMethodBinding);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
myConformance = retVal;
|
myConformance = retVal;
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkBindingForSystemOps(ConformanceRestComponent rest, Set<SystemRestfulInteraction> systemOps, BaseMethodBinding<?> nextMethodBinding) {
|
||||||
|
if (nextMethodBinding.getSystemOperationType() != null) {
|
||||||
|
String sysOpCode = nextMethodBinding.getSystemOperationType().getCode();
|
||||||
|
if (sysOpCode != null) {
|
||||||
|
SystemRestfulInteraction sysOp;
|
||||||
|
try {
|
||||||
|
sysOp = SystemRestfulInteraction.fromCode(sysOpCode);
|
||||||
|
assert sysOp != null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InternalErrorException("Unknown system-restful-interaction: " + sysOpCode);
|
||||||
|
}
|
||||||
|
if (systemOps.contains(sysOp) == false) {
|
||||||
|
systemOps.add(sysOp);
|
||||||
|
rest.addInteraction().setCode(sysOp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleDynamicSearchMethodBinding(ConformanceRestResourceComponent resource, RuntimeResourceDefinition def, TreeSet<String> includes, DynamicSearchMethodBinding searchMethodBinding) {
|
private void handleDynamicSearchMethodBinding(ConformanceRestResourceComponent resource, RuntimeResourceDefinition def, TreeSet<String> includes, DynamicSearchMethodBinding searchMethodBinding) {
|
||||||
includes.addAll(searchMethodBinding.getIncludes());
|
includes.addAll(searchMethodBinding.getIncludes());
|
||||||
|
|
||||||
|
@ -303,7 +378,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConformanceRestResourceSearchParamComponent param = resource.addSearchParam();
|
ConformanceRestResourceSearchParamComponent param = resource.addSearchParam();
|
||||||
param.setName(nextParamUnchainedName);
|
param.setName(nextParamUnchainedName);
|
||||||
if (StringUtils.isNotBlank(chain)) {
|
if (StringUtils.isNotBlank(chain)) {
|
||||||
param.addChain(chain);
|
param.addChain(chain);
|
||||||
|
@ -315,9 +390,8 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
|
||||||
for (Class<? extends IResource> nextTarget : nextParameter.getDeclaredTypes()) {
|
for (Class<? extends IResource> nextTarget : nextParameter.getDeclaredTypes()) {
|
||||||
RuntimeResourceDefinition targetDef = myRestfulServer.getFhirContext().getResourceDefinition(nextTarget);
|
RuntimeResourceDefinition targetDef = myRestfulServer.getFhirContext().getResourceDefinition(nextTarget);
|
||||||
if (targetDef != null) {
|
if (targetDef != null) {
|
||||||
ResourceType code = ResourceType.valueOf(targetDef.getName());
|
if (isNotBlank(targetDef.getName())) {
|
||||||
if (code != null) {
|
param.addTarget(targetDef.getName());
|
||||||
param.addTarget(code.name());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,8 +410,9 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of the "publisher" that will be placed in the generated conformance statement. As this is a mandatory element, the value should not be null (although this is not enforced). The
|
* Sets the value of the "publisher" that will be placed in the generated conformance statement. As this is a
|
||||||
* value defaults to "Not provided" but may be set to null, which will cause this element to be omitted.
|
* mandatory element, the value should not be null (although this is not enforced). The value defaults to
|
||||||
|
* "Not provided" but may be set to null, which will cause this element to be omitted.
|
||||||
*/
|
*/
|
||||||
public void setPublisher(String thePublisher) {
|
public void setPublisher(String thePublisher) {
|
||||||
myPublisher = thePublisher;
|
myPublisher = thePublisher;
|
||||||
|
|
|
@ -45,7 +45,7 @@ import org.hl7.fhir.instance.model.api.*;
|
||||||
* A conformance statement is a set of requirements for a desired implementation or a description of how a target application fulfills those requirements in a particular implementation.
|
* A conformance statement is a set of requirements for a desired implementation or a description of how a target application fulfills those requirements in a particular implementation.
|
||||||
*/
|
*/
|
||||||
@ResourceDef(name="Conformance", profile="http://hl7.org/fhir/Profile/Conformance")
|
@ResourceDef(name="Conformance", profile="http://hl7.org/fhir/Profile/Conformance")
|
||||||
public class Conformance extends DomainResource {
|
public class Conformance extends DomainResource implements IBaseConformance {
|
||||||
|
|
||||||
public enum RestfulConformanceMode {
|
public enum RestfulConformanceMode {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -31,20 +31,21 @@ package org.hl7.fhir.instance.model;
|
||||||
|
|
||||||
// Generated on Sun, May 31, 2015 15:45-0400 for FHIR v0.5.0
|
// Generated on Sun, May 31, 2015 15:45-0400 for FHIR v0.5.0
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.instance.model.annotations.Block;
|
||||||
import org.hl7.fhir.instance.model.annotations.ResourceDef;
|
|
||||||
import org.hl7.fhir.instance.model.annotations.SearchParamDefinition;
|
|
||||||
import org.hl7.fhir.instance.model.annotations.Child;
|
import org.hl7.fhir.instance.model.annotations.Child;
|
||||||
import org.hl7.fhir.instance.model.annotations.Description;
|
import org.hl7.fhir.instance.model.annotations.Description;
|
||||||
import org.hl7.fhir.instance.model.annotations.Block;
|
import org.hl7.fhir.instance.model.annotations.ResourceDef;
|
||||||
import org.hl7.fhir.instance.model.api.*;
|
import org.hl7.fhir.instance.model.api.IBaseBackboneElement;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
/**
|
/**
|
||||||
* A collection of error, warning or information messages that result from a system action.
|
* A collection of error, warning or information messages that result from a system action.
|
||||||
*/
|
*/
|
||||||
@ResourceDef(name="OperationOutcome", profile="http://hl7.org/fhir/Profile/OperationOutcome")
|
@ResourceDef(name="OperationOutcome", profile="http://hl7.org/fhir/Profile/OperationOutcome")
|
||||||
public class OperationOutcome extends DomainResource {
|
public class OperationOutcome extends DomainResource implements IBaseOperationOutcome {
|
||||||
|
|
||||||
public enum IssueSeverity {
|
public enum IssueSeverity {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -704,7 +704,7 @@ public class Utilities {
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
boolean lastBreak = true;
|
boolean lastBreak = true;
|
||||||
for (char c : code.toCharArray()) {
|
for (char c : code.toCharArray()) {
|
||||||
if (Character.isAlphabetic(c)) {
|
if (isAlphabetic(c)) {
|
||||||
if (lastBreak)
|
if (lastBreak)
|
||||||
b.append(Character.toUpperCase(c));
|
b.append(Character.toUpperCase(c));
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource AllergyIntolerance
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>AllergyIntolerance</sch:title>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:recorder">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:patient">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:reporter">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:substance">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:substance/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:event/f:substance">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:event/f:substance/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:event/f:manifestation">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:event/f:manifestation/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:event/f:duration">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:event/f:exposureRoute">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AllergyIntolerance/f:event/f:exposureRoute/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,90 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource Appointment
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Appointment</sch:title>
|
||||||
|
<sch:rule context="f:Appointment/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:reason">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:reason/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:slot">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:order">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:participant/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:participant/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Appointment/f:participant/f:actor">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,75 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource AppointmentResponse
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>AppointmentResponse</sch:title>
|
||||||
|
<sch:rule context="f:AppointmentResponse/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AppointmentResponse/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AppointmentResponse">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AppointmentResponse/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AppointmentResponse/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AppointmentResponse/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AppointmentResponse/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AppointmentResponse/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AppointmentResponse/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AppointmentResponse/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AppointmentResponse/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AppointmentResponse/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AppointmentResponse/f:appointment">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AppointmentResponse/f:participantType">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AppointmentResponse/f:participantType/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AppointmentResponse/f:actor">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,115 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource AuditEvent
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>AuditEvent</sch:title>
|
||||||
|
<sch:rule context="f:AuditEvent/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:event/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:event/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:event/f:subtype">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:event/f:subtype/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:event/f:purposeOfEvent">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:participant">
|
||||||
|
<sch:assert test="exists(f:userId) != exists(f:reference)">sev-3: Either a userId or a reference, but not both</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:participant/f:role">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:participant/f:role/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:participant/f:reference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:participant/f:location">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:participant/f:media">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:participant/f:purposeOfUse">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:source/f:type">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:object">
|
||||||
|
<sch:assert test="not(exists(f:name)) or not(exists(f:query))">sev-1: Either a name or a query (or both)</sch:assert>
|
||||||
|
<sch:assert test="exists(f:identifier) != exists(f:reference)">sev-2: Either an identifier or a reference, but not both</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:object/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:object/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:object/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:object/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:object/f:reference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:object/f:sensitivity">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:AuditEvent/f:object/f:sensitivity/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,75 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource Basic
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Basic</sch:title>
|
||||||
|
<sch:rule context="f:Basic/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Basic/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Basic">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Basic/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Basic/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Basic/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Basic/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Basic/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Basic/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Basic/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Basic/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Basic/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Basic/f:code">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Basic/f:code/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Basic/f:subject">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Basic/f:author">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource Binary
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Binary</sch:title>
|
||||||
|
<sch:rule context="f:Binary/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Binary/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource BodySite
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>BodySite</sch:title>
|
||||||
|
<sch:rule context="f:BodySite/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:patient">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:code">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:code/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:modifier">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:modifier/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:BodySite/f:image">
|
||||||
|
<sch:assert test="not(exists(f:data)) or exists(f:contentType)">att-1: It the Attachment has data, it SHALL have a contentType</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource Bundle
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Bundle</sch:title>
|
||||||
|
<sch:rule context="f:Bundle/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Bundle/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Bundle">
|
||||||
|
<sch:assert test="not(f:entry/f:transaction) or (f:type/@value = 'transaction') or (f:type/@value = 'history')">bdl-3: entry.transaction when (and only when) a transaction</sch:assert>
|
||||||
|
<sch:assert test="not(f:entry/f:transactionResponse) or (f:type/@value = 'transaction-response')">bdl-4: entry.transactionResponse when (and only when) a transaction-response</sch:assert>
|
||||||
|
<sch:assert test="not(f:total) or (f:type/@value = 'searchset') or (f:type/@value = 'history')">bdl-1: total only when a search or history</sch:assert>
|
||||||
|
<sch:assert test="not(f:entry/f:search) or (f:type/@value = 'searchset')">bdl-2: entry.search only when a search</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Bundle/f:entry">
|
||||||
|
<sch:assert test="f:resource or f:transaction or f:transactionResponse">bdl-5: must be a resource unless there's a transaction or transaction response</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Bundle/f:entry/f:resource/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Bundle/f:entry/f:resource/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Bundle/f:entry/f:resource/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Bundle/f:entry/f:resource/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,171 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource CarePlan
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>CarePlan</sch:title>
|
||||||
|
<sch:rule context="f:CarePlan/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:patient">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:author">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:category">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:category/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:concern">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:support">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:participant/f:role">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:participant/f:role/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:participant/f:member">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:goal">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:actionResulting">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:reference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail">
|
||||||
|
<sch:assert test="not(exists(f:detail)) or not(exists(f:simple))">cpl-3: Only provide a detail reference, or a simple detail summary</sch:assert>
|
||||||
|
<sch:assert test="(f:category/@value=('supply')) = exists(f:quantity)">cpl-2: Quantity can only be specified if activity category is supply</sch:assert>
|
||||||
|
<sch:assert test="(f:category/@value=('drug','diet')) = exists(f:dailyAmount)">cpl-1: DailyDose can only be specified if activity category is drug or food</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:code">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:code/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:reasonCodeableConcept">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:reasonCodeableConcept/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:reasonReference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:goal">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:statusReason">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:statusReason/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat">
|
||||||
|
<sch:assert test="not(exists(f:periodMax)) or exists(period)">tim-6: If there's a periodMax, there must be a period</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:durationMax)) or exists(duration)">tim-7: If there's a durationMax, there must be a duration</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:duration)) or exists(f:durationUnits)">tim-1: if there's a duration, there needs to be duration units</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:period)) or exists(f:periodUnits)">tim-2: if there's a period, there needs to be duration units</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:frequency)) or not(exists(f:when))">tim-3: Either frequency or when can exist, not both</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:bounds">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:duration">
|
||||||
|
<sch:assert test="@value >= 0 or not(@value)">tim-4: duration SHALL be a non-negative value</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:period">
|
||||||
|
<sch:assert test="@value >= 0 or not(@value)">tim-5: period SHALL be a non-negative value</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:code">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:code/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledPeriod">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:location">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:performer">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:product">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:dailyAmount">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CarePlan/f:activity/f:detail/f:quantity">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,219 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource Claim
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Claim</sch:title>
|
||||||
|
<sch:rule context="f:Claim/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:ruleset">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:originalRuleset">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:target">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:provider">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:organization">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:priority">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:fundsReserve">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:enterer">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:facility">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:prescription">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:originalPrescription">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:payee/f:type">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:payee/f:provider">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:payee/f:organization">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:payee/f:person">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:referral">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:diagnosis/f:diagnosis">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:condition">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:patient">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:coverage/f:coverage">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:coverage/f:relationship">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:coverage/f:claimResponse">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:coverage/f:originalRuleset">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:exception">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:accidentType">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:interventionException">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:type">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:provider">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:service">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:quantity">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:unitPrice">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:net">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:udi">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:bodySite">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:subSite">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:modifier">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:detail/f:type">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:detail/f:service">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:detail/f:quantity">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:detail/f:unitPrice">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:detail/f:net">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:detail/f:udi">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:detail/f:subDetail/f:type">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:detail/f:subDetail/f:service">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:detail/f:subDetail/f:quantity">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:detail/f:subDetail/f:unitPrice">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:detail/f:subDetail/f:net">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:detail/f:subDetail/f:udi">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:item/f:prosthesis/f:priorMaterial">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:additionalMaterials">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:missingTeeth/f:tooth">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Claim/f:missingTeeth/f:reason">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,180 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource ClaimResponse
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>ClaimResponse</sch:title>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:request">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:ruleset">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:originalRuleset">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:organization">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:requestProvider">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:requestOrganization">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:payeeType">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:item/f:adjudication/f:code">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:item/f:adjudication/f:amount">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:item/f:detail/f:adjudication/f:code">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:item/f:detail/f:adjudication/f:amount">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:item/f:detail/f:subDetail/f:adjudication/f:code">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:item/f:detail/f:subDetail/f:adjudication/f:amount">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:addItem/f:service">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:addItem/f:fee">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:addItem/f:adjudication/f:code">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:addItem/f:adjudication/f:amount">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:addItem/f:detail/f:service">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:addItem/f:detail/f:fee">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:addItem/f:detail/f:adjudication/f:code">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:addItem/f:detail/f:adjudication/f:amount">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:error/f:code">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:totalCost">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:unallocDeductable">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:totalBenefit">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:paymentAdjustment">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:paymentAdjustmentReason">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:paymentAmount">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:paymentRef/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:paymentRef/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:paymentRef/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:paymentRef/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:reserved">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:form">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:note/f:type">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:coverage/f:coverage">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:coverage/f:relationship">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:coverage/f:claimResponse">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClaimResponse/f:coverage/f:originalRuleset">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,105 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource ClinicalImpression
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>ClinicalImpression</sch:title>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:patient">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:assessor">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:previous">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:problem">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:triggerCodeableConcept">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:triggerCodeableConcept/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:triggerReference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:investigations/f:code">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:investigations/f:code/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:investigations/f:item">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:finding/f:item">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:finding/f:item/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:resolved">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:resolved/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:ruledOut/f:item">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:ruledOut/f:item/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:plan">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ClinicalImpression/f:action">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,99 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource Communication
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Communication</sch:title>
|
||||||
|
<sch:rule context="f:Communication/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:category">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:category/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:sender">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:recipient">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:payload/f:contentAttachment">
|
||||||
|
<sch:assert test="not(exists(f:data)) or exists(f:contentType)">att-1: It the Attachment has data, it SHALL have a contentType</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:payload/f:contentReference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:medium">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:medium/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:encounter">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:reason">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:reason/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Communication/f:subject">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,108 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource CommunicationRequest
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>CommunicationRequest</sch:title>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:category">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:category/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:sender">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:recipient">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:payload/f:contentAttachment">
|
||||||
|
<sch:assert test="not(exists(f:data)) or exists(f:contentType)">att-1: It the Attachment has data, it SHALL have a contentType</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:payload/f:contentReference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:medium">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:medium/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:requester">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:encounter">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:reason">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:reason/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:subject">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:priority">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:CommunicationRequest/f:priority/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,114 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource Composition
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Composition</sch:title>
|
||||||
|
<sch:rule context="f:Composition/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:class">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:class/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:subject">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:author">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:attester/f:party">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:custodian">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:event/f:code">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:event/f:code/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:event/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:event/f:detail">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:encounter">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:section">
|
||||||
|
<sch:assert test="(exists(f:content) and not(exists(f:section))) or (exists(f:section) and not(exists(f:content)))">cmp-1: A section must have either subsections or content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:section/f:code">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:section/f:code/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Composition/f:section/f:content">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,84 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource ConceptMap
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>ConceptMap</sch:title>
|
||||||
|
<sch:rule context="f:ConceptMap/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:useContext">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:useContext/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:contact/f:telecom">
|
||||||
|
<sch:assert test="not(exists(f:value)) or exists(f:system)">cpt-2: A system is required if a value is provided.</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:contact/f:telecom/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:sourceReference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:targetReference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:ConceptMap/f:element/f:map">
|
||||||
|
<sch:assert test="exists(f:comments) or ((f:equivalence/@value != 'narrower') and (f:equivalence/@value != 'inexact'))">cmd-1: If the map is narrower or inexact, there SHALL be some comments</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,179 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource Condition
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Condition</sch:title>
|
||||||
|
<sch:rule context="f:Condition/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:patient">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:encounter">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:asserter">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:code">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:code/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:category">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:category/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:severity">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:severity/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:onsetAge">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:onsetPeriod">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:onsetRange">
|
||||||
|
<sch:assert test="not(exists(f:low/f:value/@value)) or not(exists(f:high/f:value/@value)) or (number(f:low/f:value/@value) <= number(f:high/f:value/@value))">rng-2: If present, low SHALL have a lower value than high</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:low/f:comparator) or exists(f:high/f:comparator))">rng-3: Quantity values cannot have a comparator when used in a Range</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:onsetRange/f:low">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:onsetRange/f:high">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:abatementAge">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:abatementPeriod">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:abatementRange">
|
||||||
|
<sch:assert test="not(exists(f:low/f:value/@value)) or not(exists(f:high/f:value/@value)) or (number(f:low/f:value/@value) <= number(f:high/f:value/@value))">rng-2: If present, low SHALL have a lower value than high</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:low/f:comparator) or exists(f:high/f:comparator))">rng-3: Quantity values cannot have a comparator when used in a Range</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:abatementRange/f:low">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:abatementRange/f:high">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:stage">
|
||||||
|
<sch:assert test="exists(f:summary) or exists(f:assessment)">con-1: Stage SHALL have summary or assessment</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:stage/f:summary">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:stage/f:summary/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:stage/f:assessment">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:evidence">
|
||||||
|
<sch:assert test="exists(f:code) or exists(f:detail)">con-2: evidence SHALL have code or details</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:evidence/f:code">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:evidence/f:code/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:evidence/f:detail">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:location/f:siteCodeableConcept">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:location/f:siteCodeableConcept/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:location/f:siteReference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:dueTo">
|
||||||
|
<sch:assert test="exists(f:code) != exists(f:target)">con-4: Relationship SHALL have either a code or a target</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:dueTo/f:code">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:dueTo/f:code/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:dueTo/f:target">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:occurredFollowing">
|
||||||
|
<sch:assert test="exists(f:code) != exists(f:target)">con-5: Relationship SHALL have either a code or a target</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:occurredFollowing/f:code">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:occurredFollowing/f:code/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Condition/f:occurredFollowing/f:target">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,107 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource Conformance
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Conformance</sch:title>
|
||||||
|
<sch:rule context="f:Conformance/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance">
|
||||||
|
<sch:assert test="count(f:rest)=count(distinct-values(f:rest/f:mode/@value))">cnf-8: There can only be one REST declaration per mode</sch:assert>
|
||||||
|
<sch:assert test="count(f:document[f:mode='producer'])=count(distinct-values(f:document[f:mode='producer']/f:profile/@value)) and count(f:document[f:mode='consumer'])=count(distinct-values(f:document[f:mode='consumer']/f:profile/@value))">cnf-7: The set of documents must be unique by the combination of profile & mode</sch:assert>
|
||||||
|
<sch:assert test="count(f:messaging)<=1 or not(f:messaging[not(f:endpoint)])">cnf-4: If there is more than one messaging element, endpoint must be specified for each one</sch:assert>
|
||||||
|
<sch:assert test="count(f:messaging/f:endpoint)=count(distinct-values(f:messaging/f:endpoint/@value))">cnf-5: The set of end points listed for messaging must be unique</sch:assert>
|
||||||
|
<sch:assert test="count(f:software | f:implementation | f:description) > 0">cnf-2: A Conformance statement SHALL have at least one of description, software, or implementation</sch:assert>
|
||||||
|
<sch:assert test="exists(f:rest) or exists(f:messaging) or exists(f:document)">cnf-1: A Conformance statement SHALL have at least one of rest, messaging or document</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:contact/f:telecom">
|
||||||
|
<sch:assert test="not(exists(f:value)) or exists(f:system)">cpt-2: A system is required if a value is provided.</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:contact/f:telecom/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:profile">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:rest">
|
||||||
|
<sch:assert test="count(f:resource)=count(distinct-values(f:resource/f:type/@value))">cnf-9: A given resource can only be described once per RESTful mode</sch:assert>
|
||||||
|
<sch:assert test="count(f:query)=count(distinct-values(f:query/f:name/@value))">cnf-10: A given query can only be described once per RESTful mode</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:rest/f:security/f:service">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:rest/f:security/f:service/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:rest/f:resource">
|
||||||
|
<sch:assert test="count(f:operation)=count(distinct-values(f:operation/f:code/@value))">cnf-11: Operation codes must be unique in the context of a resource</sch:assert>
|
||||||
|
<sch:assert test="count(f:searchParam)=count(distinct-values(f:searchParam/f:name/@value))">cnf-12: Search parameter names must be unique in the context of a resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:rest/f:resource/f:profile">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:rest/f:operation/f:definition">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:messaging">
|
||||||
|
<sch:assert test="count(f:event[f:mode='sender'])=count(distinct-values(f:event[f:mode='sender']/f:code/@value)) and count(f:event[f:mode='receiver'])=count(distinct-values(f:event[f:mode='receiver']/f:code/@value))">cnf-6: The set of events per messaging endpoint must be unique by the combination of code & mode</sch:assert>
|
||||||
|
<sch:assert test="exists(f:endpoint) = exists(parent::f:Conformance/f:implementation)">cnf-3: Messaging end point is required (and is only permitted) when statement is for an implementation</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:messaging/f:event/f:code">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:messaging/f:event/f:protocol">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:messaging/f:event/f:request">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:messaging/f:event/f:response">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Conformance/f:document/f:profile">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,249 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource Contract
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Contract</sch:title>
|
||||||
|
<sch:rule context="f:Contract/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:applies">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:subject">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:authority">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:domain">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:subType">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:subType/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:action">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:action/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:actionReason">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:actionReason/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:actor/f:entity">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:actor/f:role">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:actor/f:role/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:valuedItem/f:entityCodeableConcept">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:valuedItem/f:entityCodeableConcept/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:valuedItem/f:entityReference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:valuedItem/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:valuedItem/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:valuedItem/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:valuedItem/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:valuedItem/f:quantity">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:valuedItem/f:unitPrice">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:valuedItem/f:net">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:signer/f:type">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:signer/f:party">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:applies">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:subType">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:subType/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:subject">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:action">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:action/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:actionReason">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:actionReason/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:actor/f:entity">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:actor/f:role">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:actor/f:role/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:valuedItem/f:entityCodeableConcept">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:valuedItem/f:entityCodeableConcept/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:valuedItem/f:entityReference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:valuedItem/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:valuedItem/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:valuedItem/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:valuedItem/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:valuedItem/f:quantity">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:valuedItem/f:unitPrice">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:term/f:valuedItem/f:net">
|
||||||
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:bindingAttachment">
|
||||||
|
<sch:assert test="not(exists(f:data)) or exists(f:contentType)">att-1: It the Attachment has data, it SHALL have a contentType</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:bindingReference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:friendly/f:contentAttachment">
|
||||||
|
<sch:assert test="not(exists(f:data)) or exists(f:contentType)">att-1: It the Attachment has data, it SHALL have a contentType</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:friendly/f:contentReference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:legal/f:contentAttachment">
|
||||||
|
<sch:assert test="not(exists(f:data)) or exists(f:contentType)">att-1: It the Attachment has data, it SHALL have a contentType</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:legal/f:contentReference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:rule/f:contentAttachment">
|
||||||
|
<sch:assert test="not(exists(f:data)) or exists(f:contentType)">att-1: It the Attachment has data, it SHALL have a contentType</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contract/f:rule/f:contentReference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,87 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource Contraindication
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Contraindication</sch:title>
|
||||||
|
<sch:rule context="f:Contraindication/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:patient">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:category">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:category/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:implicated">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:author">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:mitigation/f:action">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:mitigation/f:action/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Contraindication/f:mitigation/f:author">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,114 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource Coverage
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Coverage</sch:title>
|
||||||
|
<sch:rule context="f:Coverage/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:issuer">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:bin/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:bin/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:bin/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:bin/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:type">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:subscriberId/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:subscriberId/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:subscriberId/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:subscriberId/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:subscriber">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:network/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:network/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:network/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:network/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Coverage/f:contract">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,109 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource DataElement
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>DataElement</sch:title>
|
||||||
|
<sch:rule context="f:DataElement/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:useContext">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:useContext/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:contact/f:telecom">
|
||||||
|
<sch:assert test="not(exists(f:value)) or exists(f:system)">cpt-2: A system is required if a value is provided.</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:contact/f:telecom/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:element">
|
||||||
|
<sch:assert test="(not(f:max/@value) and not(f:min/@value)) or (f:max/@value = '*') or (f:max/@value >= f:min/@value)">eld-2: Min <= Max</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:nameReference) and exists(f:*[starts-with(local-name(.), 'value')]))">eld-5: Either a namereference or a fixed value (but not both) is permitted</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:*[starts-with(local-name(.), 'pattern')])) or (count(f:type)=1 )">eld-7: Pattern may only be specified if there is one type</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:*[starts-with(local-name(.), 'fixed')])) or (count(f:type)=1 )">eld-6: Fixed value may only be specified if there is one type</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:binding)) or (count(f:type/f:code) = 0) or f:type/f:code/@value=('code','Coding','CodeableConcept','Quantity','Extension', 'string', 'uri')">eld-11: Binding can only be present for coded elements, string, and uri</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:*[starts-with(local-name(.), 'pattern')])) or not(exists(f:*[starts-with(local-name(.), 'value')]))">eld-8: Pattern and value are mutually exclusive</sch:assert>
|
||||||
|
<sch:assert test="count(f:constraint) = count(distinct-values(f:constraint/f:key/@value))">eld-14: Constraints must be unique by key</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $type in f:type return $type/preceding-sibling::f:type[f:code/@value=$type/f:code/@value and f:profile/@value = $type/f:profile/@value]))">eld-13: Types must be unique by the combination of code and profile</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:*[starts-with(local-name(.), 'fixed')])) or not(exists(f:meaningWhenMissing))">eld-16: default value and meaningWhenMissing are mutually exclusive</sch:assert>
|
||||||
|
<sch:assert test="count(f:constraint[f:name]) = count(distinct-values(f:constraint/f:name/@value))">eld-15: Constraint names must be unique.</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:element/f:code">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:element/f:slicing">
|
||||||
|
<sch:assert test="(f:discriminator) or (f:definition)">eld-1: If there are no discriminators, there must be a definition</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:element/f:max">
|
||||||
|
<sch:assert test="@value='*' or (normalize-space(@value)!='' and normalize-space(translate(@value, '0123456789',''))='')">eld-3: Max SHALL be a number or "*"</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:element/f:type">
|
||||||
|
<sch:assert test="not(exists(f:aggregation)) or exists(f:code[@value = 'Reference'])">eld-4: Aggregation may only be specified if one of the allowed types for the element is a resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:element/f:binding">
|
||||||
|
<sch:assert test="(exists(f:valueSetUri) or exists(f:valueSetReference)) or exists(f:description)">eld-10: provide either a reference or a description (or both)</sch:assert>
|
||||||
|
<sch:assert test="not(f:conformance/@value='example' and f:isExtensible/@value='false')">eld-9: Example value sets are always extensible</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:element/f:binding/f:valueSetUri">
|
||||||
|
<sch:assert test="starts-with(@value, 'http:') or starts-with(@value, 'https:')">eld-12: uri SHALL start with http:// or https://</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DataElement/f:element/f:binding/f:valueSetReference">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,84 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource Device
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Device</sch:title>
|
||||||
|
<sch:rule context="f:Device/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:owner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:location">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:patient">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:contact">
|
||||||
|
<sch:assert test="not(exists(f:value)) or exists(f:system)">cpt-2: A system is required if a value is provided.</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:Device/f:contact/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,111 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource DeviceComponent
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>DeviceComponent</sch:title>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:source">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:parent">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:operationalStatus">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:operationalStatus/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:parameterGroup">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:parameterGroup/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:productionSpecification/f:specType">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:productionSpecification/f:specType/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:productionSpecification/f:componentId/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:productionSpecification/f:componentId/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:productionSpecification/f:componentId/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:productionSpecification/f:componentId/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:languageCode">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceComponent/f:languageCode/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
|
@ -0,0 +1,103 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
|
<!--
|
||||||
|
This file contains just the constraints for the resource DeviceMetric
|
||||||
|
It is provided for documentation purposes. When actually validating,
|
||||||
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
|
Alternatively you can use this file to build a smaller version of
|
||||||
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
|
resources relevant to your implementation).
|
||||||
|
-->
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>Global</sch:title>
|
||||||
|
<sch:rule context="f:*">
|
||||||
|
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
<sch:pattern>
|
||||||
|
<sch:title>DeviceMetric</sch:title>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric">
|
||||||
|
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
|
||||||
|
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||||
|
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:text/f:div">
|
||||||
|
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||||
|
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:contained/f:meta/f:security">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:contained/f:meta/f:tag">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:identifier/f:type">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:identifier/f:type/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:identifier/f:period">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:identifier/f:assigner">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:unit">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:unit/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:source">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:parent">
|
||||||
|
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:measurementPeriod/f:repeat">
|
||||||
|
<sch:assert test="not(exists(f:periodMax)) or exists(period)">tim-6: If there's a periodMax, there must be a period</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:durationMax)) or exists(duration)">tim-7: If there's a durationMax, there must be a duration</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:duration)) or exists(f:durationUnits)">tim-1: if there's a duration, there needs to be duration units</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:period)) or exists(f:periodUnits)">tim-2: if there's a period, there needs to be duration units</sch:assert>
|
||||||
|
<sch:assert test="not(exists(f:frequency)) or not(exists(f:when))">tim-3: Either frequency or when can exist, not both</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:measurementPeriod/f:repeat/f:bounds">
|
||||||
|
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:measurementPeriod/f:repeat/f:duration">
|
||||||
|
<sch:assert test="@value >= 0 or not(@value)">tim-4: duration SHALL be a non-negative value</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:measurementPeriod/f:repeat/f:period">
|
||||||
|
<sch:assert test="@value >= 0 or not(@value)">tim-5: period SHALL be a non-negative value</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:measurementPeriod/f:code">
|
||||||
|
<sch:assert test="count(f:coding[f:primary/@value='true'])<=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
<sch:rule context="f:DeviceMetric/f:measurementPeriod/f:code/f:coding">
|
||||||
|
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
|
||||||
|
</sch:rule>
|
||||||
|
</sch:pattern>
|
||||||
|
</sch:schema>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue