Wide sweeping changes to get RI structures working in server mode

This commit is contained in:
jamesagnew 2015-07-05 17:14:15 -04:00
parent 8b65a9aedf
commit 8a86ad5e76
193 changed files with 39471 additions and 890 deletions

View File

@ -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
} }

View File

@ -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>

View File

@ -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>

View File

@ -127,3 +127,5 @@ local.properties
# TeXlipse plugin # TeXlipse plugin
.texlipse .texlipse
/target/
/target/

View File

@ -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;
} }

View File

@ -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);
} }

View File

@ -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;
} }

View File

@ -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();

View File

@ -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);
} }

View File

@ -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

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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);
} }

View File

@ -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);
} }

View File

@ -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);

View File

@ -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());

View File

@ -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;

View File

@ -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);
} }
/* /*

View File

@ -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);
} }

View File

@ -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) {

View File

@ -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);

View File

@ -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());
} }

View File

@ -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) {

View File

@ -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);

View File

@ -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);
} }

View File

@ -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);

View File

@ -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;
}
} }

View File

@ -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();
}
}

View File

@ -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);
} }

View File

@ -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);
} }
} }

View File

@ -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);
} }

View File

@ -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());

View File

@ -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);

View File

@ -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;
} }

View File

@ -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;
}
} }

View File

@ -0,0 +1,6 @@
package org.hl7.fhir.instance.model.api;
public interface IBaseOperationOutcome extends IBaseResource {
}

View File

@ -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);
} }

View File

@ -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>

View File

@ -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>

View File

@ -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);

View File

@ -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);
} }

View File

@ -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;

View File

@ -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);

View File

@ -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);
} }

View File

@ -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);
}
}
} }

View File

@ -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);
}
}
} }

View File

@ -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);
} }

View File

@ -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 {

View File

@ -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());

View File

@ -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);

View File

@ -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();

View File

@ -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"));

View File

@ -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();
} }
{ {

View File

@ -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");

View File

@ -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");

View File

@ -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);
}
} }

View File

@ -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);
} }

View File

@ -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

View File

@ -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;
} }

View File

@ -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:"));
} }
} }

View File

@ -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());
}
} }

View File

@ -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();
}
} }

View File

@ -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",

View File

@ -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)) {

View File

@ -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++;
} }

View File

@ -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;

View File

@ -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());

View File

@ -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"));
} }
} }

View File

@ -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();

View File

@ -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) {

View File

@ -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();
}
} }

View File

@ -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;

View File

@ -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 {
/** /**

View File

@ -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 {
/** /**

View File

@ -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 {

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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'])&lt;=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'])&lt;=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'])&lt;=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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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'])&lt;=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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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 &lt;= 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'])&lt;=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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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'])&lt;=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>

View File

@ -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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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'])&lt;=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'])&lt;=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>

View File

@ -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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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 &lt;= 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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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 &lt;= 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 &gt;= 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 &gt;= 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'])&lt;=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 &lt;= 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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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'])&lt;=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 &lt;= 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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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'])&lt;=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'])&lt;=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'])&lt;=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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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'])&lt;=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'])&lt;=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'])&lt;=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 &lt;= 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'])&lt;=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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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'])&lt;=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 &lt;= 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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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'])&lt;=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'])&lt;=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'])&lt;=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 &lt;= 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) &lt;= 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 &lt;= 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) &lt;= 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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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 &amp; mode</sch:assert>
<sch:assert test="count(f:messaging)&lt;=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) &gt; 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 &lt;= 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'])&lt;=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 &amp; 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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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 &lt;= 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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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 &lt;= 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'])&lt;=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 &lt;= 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 &lt;= 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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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 &lt;= 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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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'])&lt;=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 &lt;= 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'])&lt;=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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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 &lt;= 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'])&lt;=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 &lt;= 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'])&lt;=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 &lt;= 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'])&lt;=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 &lt;= 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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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'])&lt;=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 &lt;= 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 &gt;= f:min/@value)">eld-2: Min &lt;= 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 &quot;*&quot;</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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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 &lt;= 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'])&lt;=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 &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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'])&lt;=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 &lt;= 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'])&lt;=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'])&lt;=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'])&lt;=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'])&lt;=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 &lt;= 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'])&lt;=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>

View File

@ -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, &lt;a&gt; 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, &lt;a&gt; 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'])&lt;=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'])&lt;=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 &lt;= 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'])&lt;=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 &lt;= 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 &gt;= 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 &gt;= 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'])&lt;=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