Udate to latest DSTU2 definitions
This commit is contained in:
commit
a9f978a8a2
|
@ -19,6 +19,6 @@ before_script:
|
|||
- export MAVEN_SKIP_RC=true
|
||||
|
||||
script:
|
||||
- mvn -B clean install && cd hapi-fhir-cobertura && mvn -B -DTRAVIS_JOB_ID=$TRAVIS_JOB_ID -P COBERTURA clean cobertura:cobertura coveralls:report
|
||||
- mvn -B clean install && cd hapi-fhir-cobertura && mvn -B -DTRAVIS_JOB_ID=$TRAVIS_JOB_ID -P COBERTURA clean test jacoco:report coveralls:report
|
||||
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ HAPI FHIR - Java API for HL7 FHIR Clients and Servers
|
|||
[![Build Status](https://travis-ci.org/jamesagnew/hapi-fhir.svg?branch=master)](https://travis-ci.org/jamesagnew/hapi-fhir)
|
||||
[![Coverage Status](https://coveralls.io/repos/jamesagnew/hapi-fhir/badge.svg?branch=master&service=github)](https://coveralls.io/github/jamesagnew/hapi-fhir?branch=master)
|
||||
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/ca.uhn.hapi.fhir/hapi-fhir-base/badge.svg)](http://search.maven.org/#search|ga|1|ca.uhn.hapi.fhir)
|
||||
[![Dependency Status](https://www.versioneye.com/user/projects/55e1d0d9c6d8f2001c00043e/badge.svg?style=flat)](https://www.versioneye.com/user/projects/55e1d0d9c6d8f2001c00043e)
|
||||
[![License](https://img.shields.io/badge/license-apache%202.0-ff69b4.svg)](https://github.com/jamesagnew/hapi-fhir/blob/master/LICENSE.txt)
|
||||
|
||||
Complete project documentation is available here:
|
||||
http://jamesagnew.github.io/hapi-fhir/
|
||||
|
|
|
@ -10,6 +10,7 @@ import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
|||
import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.QuantityDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.SimpleQuantityDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
|
||||
|
@ -167,8 +168,8 @@ public class FhirDataModel {
|
|||
observation.setValue(q);
|
||||
|
||||
// Set the reference range
|
||||
observation.getReferenceRangeFirstRep().setLow(new QuantityDt(100));
|
||||
observation.getReferenceRangeFirstRep().setHigh(new QuantityDt(200));
|
||||
observation.getReferenceRangeFirstRep().setLow(new SimpleQuantityDt(100));
|
||||
observation.getReferenceRangeFirstRep().setHigh(new SimpleQuantityDt(200));
|
||||
|
||||
// END SNIPPET: observation
|
||||
|
||||
|
|
|
@ -49,33 +49,27 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient-android</artifactId>
|
||||
<version>4.3.5.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-android</artifactId>
|
||||
<version>${slf4j_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${slf4j_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons_io_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>${commons_codec_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons_lang_version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Android does not come with the Servlet API bundled, and MethodUtil
|
||||
|
|
|
@ -22,33 +22,22 @@
|
|||
<dependency>
|
||||
<groupId>javax.json</groupId>
|
||||
<artifactId>javax.json-api</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish</groupId>
|
||||
<artifactId>javax.json</artifactId>
|
||||
<version>1.0.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- XML -->
|
||||
<dependency>
|
||||
<groupId>org.codehaus.woodstox</groupId>
|
||||
<artifactId>woodstox-core-asl</artifactId>
|
||||
<version>${woodstox_version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Only required for OpenID Connect Support -->
|
||||
<!-- <dependency> <groupId>org.mitre</groupId> <artifactId>openid-connect-client</artifactId>
|
||||
<version>${mitreid-connect-version}</version> <optional>true</optional> </dependency>
|
||||
<dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId>
|
||||
<version>2.0.2.RELEASE</version> <optional>true</optional> </dependency> -->
|
||||
<!-- -->
|
||||
|
||||
<!-- Only required for narrative generator support -->
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf</artifactId>
|
||||
<version>${thymeleaf-version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
@ -56,7 +45,6 @@
|
|||
<dependency>
|
||||
<groupId>org.ebaysf.web</groupId>
|
||||
<artifactId>cors-filter</artifactId>
|
||||
<version>${ebay_cors_filter_version}</version>
|
||||
<optional>true</optional>
|
||||
<!-- <exclusions> <exclusion> <artifactId>servlet-api</artifactId> <groupId>javax.servlet</groupId>
|
||||
</exclusion> </exclusions> -->
|
||||
|
@ -66,13 +54,11 @@
|
|||
<dependency>
|
||||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-schematron</artifactId>
|
||||
<version>${phloc_schematron_version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-commons</artifactId>
|
||||
<version>${phloc_commons_version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
@ -83,29 +69,24 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons_lang_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>${commons_codec_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons_io_version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${slf4j_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>${slf4j_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
|
|
|
@ -52,7 +52,6 @@ import org.hl7.fhir.instance.model.api.IBase;
|
|||
import org.hl7.fhir.instance.model.api.IBaseBackboneElement;
|
||||
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
||||
import org.hl7.fhir.instance.model.api.IBaseDatatypeElement;
|
||||
import org.hl7.fhir.instance.model.api.IBaseEnumFactory;
|
||||
import org.hl7.fhir.instance.model.api.IBaseEnumeration;
|
||||
import org.hl7.fhir.instance.model.api.IBaseExtension;
|
||||
import org.hl7.fhir.instance.model.api.IBaseReference;
|
||||
|
@ -626,12 +625,6 @@ class ModelScanner {
|
|||
} else if (IBaseEnumeration.class.isAssignableFrom(nextElementType)) {
|
||||
Class<?> binderType = ReflectionUtil.getGenericCollectionTypeOfFieldWithSecondOrderForList(next);
|
||||
def = new RuntimeChildPrimitiveEnumerationDatatypeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype, binderType);
|
||||
} else if (childAnnotation.enumFactory().getSimpleName().equals("NoEnumFactory") == false) {
|
||||
Class<? extends IBaseEnumFactory<?>> enumFactory = childAnnotation.enumFactory();
|
||||
def = new RuntimeChildEnumerationDatatypeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype, enumFactory);
|
||||
// } else if ("id".equals(elementName) && IIdType.class.isAssignableFrom(nextDatatype)) {
|
||||
// def = new RuntimeChildIdDatatypeDefinition(next, elementName, descriptionAnnotation,
|
||||
// childAnnotation, nextDatatype);
|
||||
} else {
|
||||
def = new RuntimeChildPrimitiveDatatypeDefinition(next, elementName, descriptionAnnotation, childAnnotation, nextDatatype);
|
||||
}
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
package ca.uhn.fhir.context;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
import org.hl7.fhir.instance.model.api.IBaseEnumFactory;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
|
||||
public class RuntimeChildEnumerationDatatypeDefinition extends RuntimeChildPrimitiveDatatypeDefinition {
|
||||
|
||||
private Class<? extends IBaseEnumFactory<?>> myBinderType;
|
||||
private volatile IBaseEnumFactory<?> myBinder;
|
||||
|
||||
public RuntimeChildEnumerationDatatypeDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, Class<? extends IBase> theDatatype,
|
||||
Class<? extends IBaseEnumFactory<?>> theBinderType) {
|
||||
super(theField, theElementName, theDescriptionAnnotation, theChildAnnotation, theDatatype);
|
||||
|
||||
myBinderType = theBinderType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBaseEnumFactory<?> getInstanceConstructorArguments() {
|
||||
IBaseEnumFactory<?> retVal = myBinder;
|
||||
if (retVal == null) {
|
||||
try {
|
||||
retVal = myBinderType.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new IllegalStateException("Failed to instantiate " + myBinderType, e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException("Failed to instantiate " + myBinderType, e);
|
||||
}
|
||||
myBinder = retVal;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
|
@ -21,6 +21,7 @@ package ca.uhn.fhir.model.api;
|
|||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -32,66 +33,56 @@ import ca.uhn.fhir.model.primitive.CodeDt;
|
|||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
|
||||
/**
|
||||
* This interface is the parent interface for all FHIR Resource definition
|
||||
* classes. Classes implementing this interface should be annotated
|
||||
* with the {@link ResourceDef @ResourceDef} annotation.
|
||||
* This interface is the parent interface for all FHIR Resource definition classes. Classes implementing this interface should be annotated with the {@link ResourceDef @ResourceDef} annotation.
|
||||
*
|
||||
* <p>
|
||||
* Note that this class is a part of HAPI's model API, used to define
|
||||
* structure classes. Users will often interact with this interface, but
|
||||
* should not need to implement it directly.
|
||||
* Note that this class is a part of HAPI's model API, used to define structure classes. Users will often interact with this interface, but should not need to implement it directly.
|
||||
* </p>
|
||||
*/
|
||||
public interface IResource extends ICompositeElement, org.hl7.fhir.instance.model.api.IBaseResource {
|
||||
public static final Include INCLUDE_ALL = new Include("*");
|
||||
public static final Set<Include> WILDCARD_ALL_SET = new HashSet<Include>(Arrays.asList(INCLUDE_ALL));
|
||||
/**
|
||||
* Include constant for <code>*</code> (return all includes)
|
||||
*/
|
||||
public static final Include INCLUDE_ALL = new Include("*", false).toLocked();
|
||||
|
||||
/**
|
||||
/**
|
||||
* Include set containing only {@link #INCLUDE_ALL}
|
||||
*/
|
||||
public static final Set<Include> WILDCARD_ALL_SET = Collections.unmodifiableSet(new HashSet<Include>(Arrays.asList(INCLUDE_ALL)));
|
||||
|
||||
/**
|
||||
* Returns the contained resource list for this resource.
|
||||
* <p>
|
||||
* Usage note: HAPI will generally populate and use the resources from this
|
||||
* list automatically (placing inline resources in the contained list when
|
||||
* encoding, and copying contained resources from this list to their
|
||||
* appropriate references when parsing) so it is generally not neccesary to
|
||||
* interact with this list directly. Instead, in a server you can place
|
||||
* resource instances in reference fields (such as <code>Patient#setManagingOrganization(ResourceReferenceDt)</code> )
|
||||
* and the resource will be automatically contained. In a client, contained resources will
|
||||
* be automatically populated into their appropriate fields by the HAPI parser.
|
||||
* Usage note: HAPI will generally populate and use the resources from this list automatically (placing inline resources in the contained list when encoding, and copying contained resources from
|
||||
* this list to their appropriate references when parsing) so it is generally not neccesary to interact with this list directly. Instead, in a server you can place resource instances in reference
|
||||
* fields (such as <code>Patient#setManagingOrganization(ResourceReferenceDt)</code> ) and the resource will be automatically contained. In a client, contained resources will be automatically
|
||||
* populated into their appropriate fields by the HAPI parser.
|
||||
* </p>
|
||||
* TODO: document contained resources and link there
|
||||
*/
|
||||
BaseContainedDt getContained();
|
||||
|
||||
/**
|
||||
* Returns the ID of this resource. Note that this identifier is the URL (or a portion
|
||||
* of the URL) used to access this resource, and is not the same thing as any business
|
||||
* identifiers stored within the resource. For example, a Patient resource might
|
||||
* have any number of medical record numbers but these are not stored here.
|
||||
* Returns the ID of this resource. Note that this identifier is the URL (or a portion of the URL) used to access this resource, and is not the same thing as any business identifiers stored within
|
||||
* the resource. For example, a Patient resource might have any number of medical record numbers but these are not stored here.
|
||||
* <p>
|
||||
* This ID is specified as the "Logical ID" and "Version ID" in the FHIR specification, see
|
||||
* <a href="http://www.hl7.org/implement/standards/fhir/resources.html#metadata">here</a>
|
||||
* This ID is specified as the "Logical ID" and "Version ID" in the FHIR specification, see <a href="http://www.hl7.org/implement/standards/fhir/resources.html#metadata">here</a>
|
||||
* </p>
|
||||
*/
|
||||
IdDt getId();
|
||||
|
||||
/**
|
||||
* Gets the language of the resource itself - <b>NOTE that this language attribute
|
||||
* applies to the resource itself, it is not (for example) the language spoken by
|
||||
* a practitioner or patient</b>
|
||||
* Gets the language of the resource itself - <b>NOTE that this language attribute applies to the resource itself, it is not (for example) the language spoken by a practitioner or patient</b>
|
||||
*/
|
||||
CodeDt getLanguage();
|
||||
|
||||
/**
|
||||
* Returns the metadata map for this object, creating it if neccesary.
|
||||
* Metadata entries are used to get/set feed bundle entries, such as the
|
||||
* resource version, or the last updated timestamp.
|
||||
* Returns the metadata map for this object, creating it if neccesary. Metadata entries are used to get/set feed bundle entries, such as the resource version, or the last updated timestamp.
|
||||
* <p>
|
||||
* Keys in this map are enumerated in the {@link ResourceMetadataKeyEnum},
|
||||
* and each key has a specific value type that it must use.
|
||||
* Keys in this map are enumerated in the {@link ResourceMetadataKeyEnum}, and each key has a specific value type that it must use.
|
||||
* </p>
|
||||
*
|
||||
* @see ResourceMetadataKeyEnum for a list of allowable keys and the object
|
||||
* types that values of a given key must use.
|
||||
* @see ResourceMetadataKeyEnum for a list of allowable keys and the object types that values of a given key must use.
|
||||
*/
|
||||
ResourceMetadataMap getResourceMetadata();
|
||||
|
||||
|
@ -99,40 +90,31 @@ public interface IResource extends ICompositeElement, org.hl7.fhir.instance.mode
|
|||
* Returns the narrative block for this resource
|
||||
*/
|
||||
BaseNarrativeDt getText();
|
||||
|
||||
|
||||
/**
|
||||
* Sets the ID of this resource. Note that this identifier is the URL (or a portion
|
||||
* of the URL) used to access this resource, and is not the same thing as any business
|
||||
* identifiers stored within the resource. For example, a Patient resource might
|
||||
* have any number of medical record numbers but these are not stored here.
|
||||
* Sets the ID of this resource. Note that this identifier is the URL (or a portion of the URL) used to access this resource, and is not the same thing as any business identifiers stored within the
|
||||
* resource. For example, a Patient resource might have any number of medical record numbers but these are not stored here.
|
||||
* <p>
|
||||
* This ID is specified as the "Logical ID" and "Version ID" in the FHIR specification, see
|
||||
* <a href="http://www.hl7.org/implement/standards/fhir/resources.html#metadata">here</a>
|
||||
* This ID is specified as the "Logical ID" and "Version ID" in the FHIR specification, see <a href="http://www.hl7.org/implement/standards/fhir/resources.html#metadata">here</a>
|
||||
* </p>
|
||||
*/
|
||||
void setId(IdDt theId);
|
||||
|
||||
/**
|
||||
* Sets the language of the resource itself - <b>NOTE that this language attribute
|
||||
* applies to the resource itself, it is not (for example) the language spoken by
|
||||
* a practitioner or patient</b>
|
||||
* Sets the language of the resource itself - <b>NOTE that this language attribute applies to the resource itself, it is not (for example) the language spoken by a practitioner or patient</b>
|
||||
*/
|
||||
void setLanguage(CodeDt theLanguage);
|
||||
|
||||
/**
|
||||
* Sets the metadata map for this object. Metadata entries are used to
|
||||
* get/set feed bundle entries, such as the resource version, or the last
|
||||
* updated timestamp.
|
||||
* Sets the metadata map for this object. Metadata entries are used to get/set feed bundle entries, such as the resource version, or the last updated timestamp.
|
||||
*
|
||||
* @throws NullPointerException
|
||||
* The map must not be null
|
||||
* The map must not be null
|
||||
*/
|
||||
void setResourceMetadata(ResourceMetadataMap theMap);
|
||||
|
||||
/**
|
||||
* Returns a String representing the name of this Resource. This return
|
||||
* value is not used for anything by HAPI itself, but is provided as a
|
||||
* convenience to developers using the API.
|
||||
* Returns a String representing the name of this Resource. This return value is not used for anything by HAPI itself, but is provided as a convenience to developers using the API.
|
||||
*
|
||||
* @return the name of this resource, e.g. "Patient", or "Observation"
|
||||
*/
|
||||
|
@ -141,7 +123,6 @@ public interface IResource extends ICompositeElement, org.hl7.fhir.instance.mode
|
|||
/**
|
||||
* Returns the FHIR version represented by this structure
|
||||
*/
|
||||
public ca.uhn.fhir.context.FhirVersionEnum getStructureFhirVersionEnum();
|
||||
public ca.uhn.fhir.context.FhirVersionEnum getStructureFhirVersionEnum();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ public class Include {
|
|||
|
||||
private boolean myRecurse;
|
||||
private String myValue;
|
||||
private boolean myImmutable;
|
||||
|
||||
/**
|
||||
* Constructor for <b>non-recursive</b> include
|
||||
|
@ -125,9 +126,18 @@ public class Include {
|
|||
}
|
||||
|
||||
public void setValue(String theValue) {
|
||||
if (myImmutable) {
|
||||
throw new IllegalStateException("Can not change the value of this include");
|
||||
}
|
||||
myValue = theValue;
|
||||
}
|
||||
|
||||
public Include toLocked() {
|
||||
Include retVal = new Include(myValue, myRecurse);
|
||||
retVal.myImmutable = true;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder builder = new ToStringBuilder(this);
|
||||
|
|
|
@ -24,11 +24,6 @@ import java.lang.annotation.ElementType;
|
|||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import net.sourceforge.cobertura.CoverageIgnore;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseEnumFactory;
|
||||
|
||||
import ca.uhn.fhir.model.api.IElement;
|
||||
|
||||
|
@ -112,32 +107,4 @@ public @interface Child {
|
|||
*/
|
||||
boolean summary() default false;
|
||||
|
||||
/**
|
||||
* For children which accept an {@link Enumeration} as the type, this
|
||||
* field indicates the type to use for the enum factory
|
||||
*/
|
||||
Class<? extends IBaseEnumFactory<?>> enumFactory() default NoEnumFactory.class;
|
||||
|
||||
@CoverageIgnore
|
||||
public static class NoEnumFactory implements IBaseEnumFactory<Enum<?>> {
|
||||
|
||||
@CoverageIgnore
|
||||
private NoEnumFactory() {
|
||||
// non instantiable
|
||||
}
|
||||
|
||||
@CoverageIgnore
|
||||
@Override
|
||||
public Enum<?> fromCode(String theCodeString) throws IllegalArgumentException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@CoverageIgnore
|
||||
@Override
|
||||
public String toCode(Enum<?> theCode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -199,6 +199,34 @@ public class IdDt extends UriDt implements IPrimitiveDatatype<String>, IIdType {
|
|||
return getIdPartAsBigDecimal();
|
||||
}
|
||||
|
||||
private String determineLocalPrefix(String theValue) {
|
||||
if (theValue == null || theValue.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (theValue.startsWith("#")) {
|
||||
return "#";
|
||||
}
|
||||
int lastPrefix = -1;
|
||||
for (int i = 0; i < theValue.length(); i++) {
|
||||
char nextChar = theValue.charAt(i);
|
||||
if (nextChar == ':') {
|
||||
lastPrefix = i;
|
||||
} else if (!Character.isLetter(nextChar) || !Character.isLowerCase(nextChar)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lastPrefix != -1) {
|
||||
String candidate = theValue.substring(0, lastPrefix + 1);
|
||||
if (candidate.startsWith("cid:") || candidate.startsWith("urn:")) {
|
||||
return candidate;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object theArg0) {
|
||||
if (!(theArg0 instanceof IdDt)) {
|
||||
|
@ -383,6 +411,34 @@ public class IdDt extends UriDt implements IPrimitiveDatatype<String>, IIdType {
|
|||
return isBlank(getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIdPartValid() {
|
||||
String id = getIdPart();
|
||||
if (StringUtils.isBlank(id)) {
|
||||
return false;
|
||||
}
|
||||
if (id.length() > 64) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < id.length(); i++) {
|
||||
char nextChar = id.charAt(i);
|
||||
if (nextChar >= 'a' && nextChar <= 'z') {
|
||||
continue;
|
||||
}
|
||||
if (nextChar >= 'A' && nextChar <= 'Z') {
|
||||
continue;
|
||||
}
|
||||
if (nextChar >= '0' && nextChar <= '9') {
|
||||
continue;
|
||||
}
|
||||
if (nextChar == '-' || nextChar == '.') {
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the unqualified ID is a valid {@link Long} value (in other words, it consists only of digits)
|
||||
*/
|
||||
|
@ -407,7 +463,7 @@ public class IdDt extends UriDt implements IPrimitiveDatatype<String>, IIdType {
|
|||
public boolean isLocal() {
|
||||
return "#".equals(myBaseUrl);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies the value from the given IdDt to <code>this</code> IdDt. It is generally not neccesary to use this method but it is provided for consistency with the rest of the API.
|
||||
*/
|
||||
|
@ -416,34 +472,6 @@ public class IdDt extends UriDt implements IPrimitiveDatatype<String>, IIdType {
|
|||
setValue(theId.getValue());
|
||||
}
|
||||
|
||||
private String determineLocalPrefix(String theValue) {
|
||||
if (theValue == null || theValue.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (theValue.startsWith("#")) {
|
||||
return "#";
|
||||
}
|
||||
int lastPrefix = -1;
|
||||
for (int i = 0; i < theValue.length(); i++) {
|
||||
char nextChar = theValue.charAt(i);
|
||||
if (nextChar == ':') {
|
||||
lastPrefix = i;
|
||||
} else if (!Character.isLetter(nextChar) || !Character.isLowerCase(nextChar)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lastPrefix != -1) {
|
||||
String candidate = theValue.substring(0, lastPrefix + 1);
|
||||
if (candidate.startsWith("cid:") || candidate.startsWith("urn:")) {
|
||||
return candidate;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value
|
||||
*
|
||||
|
@ -602,6 +630,14 @@ public class IdDt extends UriDt implements IPrimitiveDatatype<String>, IIdType {
|
|||
return new IdDt(value + '/' + Constants.PARAM_HISTORY + '/' + theVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new ID with with form "urn:uuid:[UUID]" where [UUID] is a new, randomly
|
||||
* created UUID generated by {@link UUID#randomUUID()}
|
||||
*/
|
||||
public static IdDt newRandomUuid() {
|
||||
return new IdDt("urn:uuid:" + UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the ID from the given resource instance
|
||||
*/
|
||||
|
@ -634,12 +670,4 @@ public class IdDt extends UriDt implements IPrimitiveDatatype<String>, IIdType {
|
|||
return theIdPart.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new ID with with form "urn:uuid:[UUID]" where [UUID] is a new, randomly
|
||||
* created UUID generated by {@link UUID#randomUUID()}
|
||||
*/
|
||||
public static IdDt newRandomUuid() {
|
||||
return new IdDt("urn:uuid:" + UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link CompositeClientParam} instead. That class is identical to this one but was renamed to reduce
|
||||
* confusing duplicate names in the API. This class will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class CompositeParam<A extends IParam, B extends IParam> extends CompositeClientParam<A,B> {
|
||||
|
||||
public CompositeParam(String theParamName) {
|
||||
super(theParamName);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link DateClientParam} instead. That class is identical to this one but was renamed to reduct
|
||||
* confusing duplicate names in the API. This class will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class DateParam extends DateClientParam {
|
||||
|
||||
public DateParam(String theParamName) {
|
||||
super(theParamName);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link NumberClientParam} instead. That class is identical to this one but was renamed to reduct
|
||||
* confusing duplicate names in the API. This class will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class NumberParam extends NumberClientParam {
|
||||
|
||||
public NumberParam(String theParamName) {
|
||||
super(theParamName);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link QuantityClientParam} instead. That class is identical to this one but was renamed to reduct
|
||||
* confusing duplicate names in the API. This class will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class QuantityParam extends QuantityClientParam {
|
||||
|
||||
public QuantityParam(String theParamName) {
|
||||
super(theParamName);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link ReferenceClientParam} instead. That class is identical to this one but was renamed to reduct
|
||||
* confusing duplicate names in the API. This class will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class ReferenceParam extends ReferenceClientParam {
|
||||
|
||||
public ReferenceParam(String theParamName) {
|
||||
super(theParamName);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link StringClientParam} instead. That class is identical to this one but was renamed to reduct
|
||||
* confusing duplicate names in the API. This class will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class StringParam extends StringClientParam {
|
||||
|
||||
public StringParam(String theParamName) {
|
||||
super(theParamName);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package ca.uhn.fhir.rest.gclient;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link TokenClientParam} instead. That class is identical to this one but was renamed to reduct
|
||||
* confusing duplicate names in the API. This class will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
public class TokenParam extends TokenClientParam {
|
||||
|
||||
public TokenParam(String theParamName) {
|
||||
super(theParamName);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -42,20 +42,22 @@ public class TokenParam extends BaseParam implements IQueryParameterType {
|
|||
}
|
||||
|
||||
/**
|
||||
* Constructor which copies the {@link InternalCodingDt#getSystemElement() system} and {@link InternalCodingDt#getCodeElement() code} from a {@link InternalCodingDt} instance and adds it as a parameter
|
||||
* Constructor which copies the {@link InternalCodingDt#getSystemElement() system} and {@link InternalCodingDt#getCodeElement() code} from a {@link InternalCodingDt} instance and adds it as a
|
||||
* parameter
|
||||
*
|
||||
* @param theCodingDt
|
||||
* The coding
|
||||
* The coding
|
||||
*/
|
||||
public TokenParam(BaseCodingDt theCodingDt) {
|
||||
this(toSystemValue(theCodingDt.getSystemElement()), theCodingDt.getCodeElement().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor which copies the {@link BaseIdentifierDt#getSystemElement() system} and {@link BaseIdentifierDt#getValueElement() value} from a {@link BaseIdentifierDt} instance and adds it as a parameter
|
||||
* Constructor which copies the {@link BaseIdentifierDt#getSystemElement() system} and {@link BaseIdentifierDt#getValueElement() value} from a {@link BaseIdentifierDt} instance and adds it as a
|
||||
* parameter
|
||||
*
|
||||
* @param theIdentifierDt
|
||||
* The identifier
|
||||
* The identifier
|
||||
*/
|
||||
public TokenParam(BaseIdentifierDt theIdentifierDt) {
|
||||
this(toSystemValue(theIdentifierDt.getSystemElement()), theIdentifierDt.getValueElement().getValue());
|
||||
|
@ -102,12 +104,18 @@ public class TokenParam extends BaseParam implements IQueryParameterType {
|
|||
*/
|
||||
@Override
|
||||
void doSetValueAsQueryToken(String theQualifier, String theParameter) {
|
||||
int barIndex = ParameterUtil.nonEscapedIndexOf(theParameter, '|');
|
||||
if (barIndex != -1) {
|
||||
setSystem(theParameter.substring(0, barIndex));
|
||||
setValue(ParameterUtil.unescape(theParameter.substring(barIndex + 1)));
|
||||
setText(Constants.PARAMQUALIFIER_TOKEN_TEXT.equals(theQualifier));
|
||||
setSystem(null);
|
||||
if (theParameter == null) {
|
||||
setValue(null);
|
||||
} else {
|
||||
setValue(ParameterUtil.unescape(theParameter));
|
||||
int barIndex = ParameterUtil.nonEscapedIndexOf(theParameter, '|');
|
||||
if (barIndex != -1) {
|
||||
setSystem(theParameter.substring(0, barIndex));
|
||||
setValue(ParameterUtil.unescape(theParameter.substring(barIndex + 1)));
|
||||
} else {
|
||||
setValue(ParameterUtil.unescape(theParameter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -288,7 +288,7 @@ public class RestfulServer extends HttpServlet {
|
|||
|
||||
/**
|
||||
* Returns the default encoding to return (XML/JSON) if an incoming request does not specify a preference (either with the <code>_format</code> URL parameter, or with an <code>Accept</code> header
|
||||
* in the request. The default is {@link EncodingEnum#XML}.
|
||||
* in the request. The default is {@link EncodingEnum#XML}. Will not return null.
|
||||
*/
|
||||
public EncodingEnum getDefaultResponseEncoding() {
|
||||
return myDefaultResponseEncoding;
|
||||
|
|
|
@ -19,8 +19,8 @@ package ca.uhn.fhir.rest.server;
|
|||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
@ -92,6 +92,46 @@ public class RestfulServerUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void configureResponseParser(RequestDetails theRequestDetails, IParser parser) {
|
||||
// Pretty print
|
||||
boolean prettyPrint = RestfulServerUtils.prettyPrintResponse(theRequestDetails.getServer(), theRequestDetails);
|
||||
|
||||
parser.setPrettyPrint(prettyPrint);
|
||||
parser.setServerBaseUrl(theRequestDetails.getFhirServerBase());
|
||||
|
||||
// Summary mode
|
||||
Set<SummaryEnum> summaryMode = RestfulServerUtils.determineSummaryMode(theRequestDetails);
|
||||
|
||||
// _elements
|
||||
Set<String> elements = ElementsParameter.getElementsValueOrNull(theRequestDetails);
|
||||
if (elements != null && summaryMode != null && !summaryMode.equals(Collections.singleton(SummaryEnum.FALSE))) {
|
||||
throw new InvalidRequestException("Cannot combine the " + Constants.PARAM_SUMMARY + " and " + Constants.PARAM_ELEMENTS + " parameters");
|
||||
}
|
||||
Set<String> elementsAppliesTo = null;
|
||||
if (elements != null && isNotBlank(theRequestDetails.getResourceName())) {
|
||||
elementsAppliesTo = Collections.singleton(theRequestDetails.getResourceName());
|
||||
}
|
||||
|
||||
if (summaryMode != null) {
|
||||
if (summaryMode.contains(SummaryEnum.COUNT)) {
|
||||
parser.setEncodeElements(Collections.singleton("Bundle.total"));
|
||||
} else if (summaryMode.contains(SummaryEnum.TEXT)) {
|
||||
parser.setEncodeElements(TEXT_ENCODE_ELEMENTS);
|
||||
} else {
|
||||
parser.setSuppressNarratives(summaryMode.contains(SummaryEnum.DATA));
|
||||
parser.setSummaryMode(summaryMode.contains(SummaryEnum.TRUE));
|
||||
}
|
||||
}
|
||||
if (elements != null && elements.size() > 0) {
|
||||
Set<String> newElements = new HashSet<String>();
|
||||
for (String next : elements) {
|
||||
newElements.add("*." + next);
|
||||
}
|
||||
parser.setEncodeElements(newElements);
|
||||
parser.setEncodeElementsAppliesToResourceTypes(elementsAppliesTo);
|
||||
}
|
||||
}
|
||||
|
||||
public static String createPagingLink(Set<Include> theIncludes, String theServerBase, String theSearchId, int theOffset, int theCount, EncodingEnum theResponseEncoding, boolean thePrettyPrint) {
|
||||
try {
|
||||
StringBuilder b = new StringBuilder();
|
||||
|
@ -235,8 +275,7 @@ public class RestfulServerUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Determine whether a response should be given in JSON or XML format based on the incoming HttpServletRequest's
|
||||
* <code>"_format"</code> parameter and <code>"Accept:"</code> HTTP header.
|
||||
* Determine whether a response should be given in JSON or XML format based on the incoming HttpServletRequest's <code>"_format"</code> parameter and <code>"Accept:"</code> HTTP header.
|
||||
*/
|
||||
public static EncodingEnum determineResponseEncodingWithDefault(RestfulServer theServer, HttpServletRequest theReq) {
|
||||
EncodingEnum retVal = determineResponseEncodingNoDefault(theReq);
|
||||
|
@ -253,8 +292,7 @@ public class RestfulServerUtils {
|
|||
|
||||
if (retVal == null) {
|
||||
/*
|
||||
* HAPI originally supported a custom parameter called _narrative, but this has been superceded by an official
|
||||
* parameter called _summary
|
||||
* HAPI originally supported a custom parameter called _narrative, but this has been superceded by an official parameter called _summary
|
||||
*/
|
||||
String[] narrative = requestParams.get(Constants.PARAM_NARRATIVE);
|
||||
if (narrative != null && narrative.length > 0) {
|
||||
|
@ -288,16 +326,12 @@ public class RestfulServerUtils {
|
|||
}
|
||||
|
||||
public static IParser getNewParser(FhirContext theContext, RequestDetails theRequestDetails) {
|
||||
|
||||
// Pretty print
|
||||
boolean prettyPrint = RestfulServerUtils.prettyPrintResponse(theRequestDetails.getServer(), theRequestDetails);
|
||||
|
||||
// Determine response encoding
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequestDetails.getServletRequest());
|
||||
if (responseEncoding == null) {
|
||||
responseEncoding = theRequestDetails.getServer().getDefaultResponseEncoding();
|
||||
}
|
||||
|
||||
IParser parser;
|
||||
switch (responseEncoding) {
|
||||
case JSON:
|
||||
|
@ -308,41 +342,9 @@ public class RestfulServerUtils {
|
|||
parser = theContext.newXmlParser();
|
||||
break;
|
||||
}
|
||||
parser.setPrettyPrint(prettyPrint);
|
||||
parser.setServerBaseUrl(theRequestDetails.getFhirServerBase());
|
||||
|
||||
// Summary mode
|
||||
Set<SummaryEnum> summaryMode = RestfulServerUtils.determineSummaryMode(theRequestDetails);
|
||||
|
||||
// _elements
|
||||
Set<String> elements = ElementsParameter.getElementsValueOrNull(theRequestDetails);
|
||||
if (elements != null && summaryMode != null && !summaryMode.equals(Collections.singleton(SummaryEnum.FALSE))) {
|
||||
throw new InvalidRequestException("Cannot combine the " + Constants.PARAM_SUMMARY + " and " + Constants.PARAM_ELEMENTS + " parameters");
|
||||
}
|
||||
Set<String> elementsAppliesTo = null;
|
||||
if (elements != null && isNotBlank(theRequestDetails.getResourceName())) {
|
||||
elementsAppliesTo = Collections.singleton(theRequestDetails.getResourceName());
|
||||
}
|
||||
|
||||
if (summaryMode != null) {
|
||||
if (summaryMode.contains(SummaryEnum.COUNT)) {
|
||||
parser.setEncodeElements(Collections.singleton("Bundle.total"));
|
||||
} else if (summaryMode.contains(SummaryEnum.TEXT)) {
|
||||
parser.setEncodeElements(TEXT_ENCODE_ELEMENTS);
|
||||
} else {
|
||||
parser.setSuppressNarratives(summaryMode.contains(SummaryEnum.DATA));
|
||||
parser.setSummaryMode(summaryMode.contains(SummaryEnum.TRUE));
|
||||
}
|
||||
}
|
||||
if (elements != null && elements.size() > 0) {
|
||||
Set<String> newElements = new HashSet<String>();
|
||||
for (String next : elements) {
|
||||
newElements.add("*." + next);
|
||||
}
|
||||
parser.setEncodeElements(newElements);
|
||||
parser.setEncodeElementsAppliesToResourceTypes(elementsAppliesTo);
|
||||
}
|
||||
|
||||
configureResponseParser(theRequestDetails, parser);
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
|
@ -357,6 +359,55 @@ public class RestfulServerUtils {
|
|||
return writer;
|
||||
}
|
||||
|
||||
public static Set<String> parseAcceptHeaderAndReturnHighestRankedOptions(HttpServletRequest theRequest) {
|
||||
Set<String> retVal = new HashSet<String>();
|
||||
|
||||
Enumeration<String> acceptValues = theRequest.getHeaders(Constants.HEADER_ACCEPT);
|
||||
if (acceptValues != null) {
|
||||
float bestQ = -1f;
|
||||
while (acceptValues.hasMoreElements()) {
|
||||
String nextAcceptHeaderValue = acceptValues.nextElement();
|
||||
Matcher m = ACCEPT_HEADER_PATTERN.matcher(nextAcceptHeaderValue);
|
||||
float q = 1.0f;
|
||||
while (m.find()) {
|
||||
String contentTypeGroup = m.group(1);
|
||||
if (isNotBlank(contentTypeGroup)) {
|
||||
|
||||
String name = m.group(3);
|
||||
String value = m.group(4);
|
||||
if (name != null && value != null) {
|
||||
if ("q".equals(name)) {
|
||||
try {
|
||||
q = Float.parseFloat(value);
|
||||
q = Math.max(q, 0.0f);
|
||||
} catch (NumberFormatException e) {
|
||||
ourLog.debug("Invalid Accept header q value: {}", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (q > bestQ) {
|
||||
retVal.clear();
|
||||
bestQ = q;
|
||||
}
|
||||
|
||||
if (q == bestQ) {
|
||||
retVal.add(contentTypeGroup.trim());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!",".equals(m.group(5))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static PreferReturnEnum parsePreferHeader(String theValue) {
|
||||
if (isBlank(theValue)) {
|
||||
return null;
|
||||
|
@ -414,8 +465,8 @@ public class RestfulServerUtils {
|
|||
return prettyPrint;
|
||||
}
|
||||
|
||||
public static void streamResponseAsBundle(RestfulServer theServer, HttpServletResponse theHttpResponse, Bundle bundle, String theServerBase, Set<SummaryEnum> theSummaryMode, boolean theRespondGzip, boolean theRequestIsBrowser, RequestDetails theRequestDetails)
|
||||
throws IOException {
|
||||
public static void streamResponseAsBundle(RestfulServer theServer, HttpServletResponse theHttpResponse, Bundle bundle, String theServerBase, Set<SummaryEnum> theSummaryMode, boolean theRespondGzip,
|
||||
boolean theRequestIsBrowser, RequestDetails theRequestDetails) throws IOException {
|
||||
assert!theServerBase.endsWith("/");
|
||||
|
||||
theHttpResponse.setStatus(200);
|
||||
|
@ -446,8 +497,8 @@ public class RestfulServerUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IBaseResource theResource, boolean theRequestIsBrowser, Set<SummaryEnum> theSummaryMode, int stausCode, boolean theRespondGzip,
|
||||
boolean theAddContentLocationHeader, RequestDetails theRequestDetails) throws IOException {
|
||||
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IBaseResource theResource, boolean theRequestIsBrowser, Set<SummaryEnum> theSummaryMode,
|
||||
int stausCode, boolean theRespondGzip, boolean theAddContentLocationHeader, RequestDetails theRequestDetails) throws IOException {
|
||||
theHttpResponse.setStatus(stausCode);
|
||||
|
||||
// Determine response encoding
|
||||
|
@ -497,12 +548,12 @@ public class RestfulServerUtils {
|
|||
|
||||
// Ok, we're not serving a binary resource, so apply default encoding
|
||||
responseEncoding = responseEncoding != null ? responseEncoding : theServer.getDefaultResponseEncoding();
|
||||
|
||||
|
||||
boolean encodingDomainResourceAsText = theSummaryMode.contains(SummaryEnum.TEXT);
|
||||
if (encodingDomainResourceAsText) {
|
||||
/*
|
||||
* If the user requests "text" for a bundle, only suppress the non text elements in the Element.entry.resource
|
||||
* parts, we're not streaming just the narrative as HTML (since bundles don't even have one)
|
||||
* If the user requests "text" for a bundle, only suppress the non text elements in the Element.entry.resource parts, we're not streaming just the narrative as HTML (since bundles don't even
|
||||
* have one)
|
||||
*/
|
||||
if ("Bundle".equals(theServer.getFhirContext().getResourceDefinition(theResource).getName())) {
|
||||
encodingDomainResourceAsText = false;
|
||||
|
|
|
@ -21,6 +21,7 @@ package ca.uhn.fhir.rest.server.interceptor;
|
|||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -166,8 +167,8 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
|
|||
/*
|
||||
* It's not a browser...
|
||||
*/
|
||||
String accept = theServletRequest.getHeader(Constants.HEADER_ACCEPT);
|
||||
if (accept == null || !accept.toLowerCase().contains("html")) {
|
||||
Set<String> highestRankedAcceptValues = RestfulServerUtils.parseAcceptHeaderAndReturnHighestRankedOptions(theRequestDetails.getServletRequest());
|
||||
if (highestRankedAcceptValues.contains(Constants.CT_HTML) == false) {
|
||||
return super.outgoingResponse(theRequestDetails, theResponseObject, theServletRequest, theServletResponse);
|
||||
}
|
||||
|
||||
|
@ -192,11 +193,16 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
|
|||
}
|
||||
|
||||
private void streamResponse(RequestDetails theRequestDetails, HttpServletResponse theServletResponse, IBaseResource resource) {
|
||||
|
||||
IParser p = RestfulServerUtils.getNewParser(theRequestDetails.getServer().getFhirContext(), theRequestDetails);
|
||||
IParser p;
|
||||
if (theRequestDetails.getParameters().containsKey(Constants.PARAM_FORMAT)) {
|
||||
p = RestfulServerUtils.getNewParser(theRequestDetails.getServer().getFhirContext(), theRequestDetails);
|
||||
} else {
|
||||
EncodingEnum defaultResponseEncoding = theRequestDetails.getServer().getDefaultResponseEncoding();
|
||||
p = defaultResponseEncoding.newParser(theRequestDetails.getServer().getFhirContext());
|
||||
RestfulServerUtils.configureResponseParser(theRequestDetails, p);
|
||||
}
|
||||
|
||||
EncodingEnum encoding = p.getEncoding();
|
||||
|
||||
String encoded = p.encodeResourceToString(resource);
|
||||
|
||||
theServletResponse.setContentType(Constants.CT_HTML_WITH_UTF8);
|
||||
|
@ -245,8 +251,8 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
|
|||
/*
|
||||
* It's not a browser...
|
||||
*/
|
||||
String accept = theServletRequest.getHeader(Constants.HEADER_ACCEPT);
|
||||
if (accept == null || !accept.toLowerCase().contains("html")) {
|
||||
Set<String> accept = RestfulServerUtils.parseAcceptHeaderAndReturnHighestRankedOptions(theRequestDetails.getServletRequest());
|
||||
if (!accept.contains(Constants.CT_HTML)) {
|
||||
return super.handleException(theRequestDetails, theException, theServletRequest, theServletResponse);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,14 @@ package ca.uhn.fhir.util;
|
|||
*/
|
||||
|
||||
public class ExtensionConstants {
|
||||
|
||||
/**
|
||||
* Non instantiable
|
||||
*/
|
||||
private ExtensionConstants() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
public static final String PARAM_IS_REQUIRED = "http://hl7api.sourceforge.net/hapi-fhir/extensions.xml#paramIsRequired";
|
||||
|
||||
public static final String QUERY_RETURN_TYPE = "http://hl7api.sourceforge.net/hapi-fhir/extensions.xml#queryReturnType";
|
||||
|
|
|
@ -92,6 +92,19 @@ public interface IIdType {
|
|||
*/
|
||||
boolean isAbsolute();
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the {@link #getIdPart() ID part of this object} is valid according to the FHIR rules for valid IDs.
|
||||
* <p>
|
||||
* The FHIR specification states:
|
||||
* <code>Any combination of upper or lower case ASCII letters ('A'..'Z', and 'a'..'z', numerals ('0'..'9'), '-' and '.', with a length limit of 64 characters. (This might be an integer, an un-prefixed OID, UUID or any other identifier pattern that meets these constraints.) regex: [A-Za-z0-9\-\.]{1,64}</code>
|
||||
* </p>
|
||||
*/
|
||||
boolean isIdPartValid();
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the {@link #getIdPart() ID part of this object} contains
|
||||
* only numbers
|
||||
*/
|
||||
boolean isIdPartValidLong();
|
||||
|
||||
Long getIdPartAsLong();
|
||||
|
|
|
@ -52,7 +52,8 @@ ca.uhn.fhir.jpa.dao.BaseHapiFhirSystemDao.transactionMissingUrl=Unable to perfor
|
|||
ca.uhn.fhir.jpa.dao.BaseHapiFhirSystemDao.transactionInvalidUrl=Unable to perform {0}, URL provided is invalid: {1}
|
||||
|
||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao.duplicateCreateForcedId=Can not create entity with ID[{0}], a resource with this ID already exists
|
||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao.failedToCreateWithClientAssignedNumericId=Can not create resource with ID[{0}], no resource with this ID exists and clients may only assign IDs which begin with a non-numeric character on this server
|
||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao.failedToCreateWithInvalidId=Can not process entity with ID[{0}], this is not a valid FHIR ID
|
||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao.failedToCreateWithClientAssignedNumericId=Can not create resource with ID[{0}], no resource with this ID exists and clients may only assign IDs which contain at least one non-numeric character
|
||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao.failedToCreateWithClientAssignedId=Can not create resource with ID[{0}], ID must not be supplied on a create (POST) operation
|
||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao.invalidParameterChain=Invalid parameter chain: {0}
|
||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao.multipleParamsWithSameNameOneIsMissingTrue=This server does not know how to handle multiple "{0}" parameters where one has a value of :missing=true
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
/build/
|
||||
/target/
|
|
@ -1,27 +1,20 @@
|
|||
<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>
|
||||
|
||||
<!--
|
||||
Note: HAPI projects use the "hapi-fhir" POM as their base to provide
|
||||
easy management.
|
||||
|
||||
You do not need to use this in your own projects, so the
|
||||
"parent" tag and it's contents below may be removed if you
|
||||
are using this file as a basis for your own project.
|
||||
-->
|
||||
<!-- Note: HAPI projects use the "hapi-fhir" POM as their base to provide easy management. You do not need to use this in your own projects, so the "parent" tag
|
||||
and it's contents below may be removed if you are using this file as a basis for your own project. -->
|
||||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
<groupId>ca.uhn.hapi.example</groupId>
|
||||
<artifactId>hapi-fhir-examples-uploader</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<artifactId>hapi-fhir-cli</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>HAPI FHIR - Examples Uploader</name>
|
||||
<name>HAPI FHIR - Command Line Client</name>
|
||||
|
||||
<dependencies>
|
||||
|
||||
|
@ -29,42 +22,52 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
<!--
|
||||
Tells Maven to name the generated WAR file as
|
||||
hapi-fhir-jpaserver-example.war
|
||||
-->
|
||||
|
||||
<!-- Tells Maven to name the generated WAR file as hapi-fhir-jpaserver-example.war -->
|
||||
<finalName>hapi-fhir-jpaserver-example</finalName>
|
||||
|
||||
<!--
|
||||
The following is not required for the application to build, but
|
||||
allows you to test it by issuing "mvn jetty:run" from the command
|
||||
line.
|
||||
-->
|
||||
|
||||
<!-- The following is not required for the application to build, but allows you to test it by issuing "mvn jetty:run" from the command line. -->
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
@ -79,11 +82,9 @@
|
|||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
|
||||
|
||||
<plugins>
|
||||
<!--
|
||||
Tell Maven which Java source version you want to use
|
||||
-->
|
||||
<!-- Tell Maven which Java source version you want to use -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
|
@ -92,11 +93,8 @@
|
|||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!--
|
||||
The configuration here tells the WAR plugin to include the FHIR Tester
|
||||
overlay. You can omit it if you are not using that feature.
|
||||
-->
|
||||
|
||||
<!-- The configuration here tells the WAR plugin to include the FHIR Tester overlay. You can omit it if you are not using that feature. -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
|
@ -109,11 +107,8 @@
|
|||
</overlays>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!--
|
||||
This plugin is just a part of the HAPI internal build process, you do not
|
||||
need to incude it in your own projects
|
||||
-->
|
||||
|
||||
<!-- This plugin is just a part of the HAPI internal build process, you do not need to incude it in your own projects -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
|
@ -121,7 +116,7 @@
|
|||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package ca.uhn.fhir.cli;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
|
||||
public class BaseCommand {
|
||||
|
||||
public BaseCommand() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected IGenericClient newClient(FhirContext ctx) {
|
||||
IGenericClient fhirClient = ctx.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu2");
|
||||
return fhirClient;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
package ca.uhn.fhir.exampleuploader;
|
||||
package ca.uhn.fhir.cli;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -21,18 +22,22 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.EntryTransaction;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.EntryRequest;
|
||||
import ca.uhn.fhir.model.dstu2.resource.SearchParameter;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.HTTPVerbEnum;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
import ca.uhn.fhir.util.ResourceReferenceInfo;
|
||||
|
||||
public class Uploader {
|
||||
public class ExampleDataUploader extends BaseCommand {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(Uploader.class);
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExampleDataUploader.class);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new ExampleDataUploader().execute();
|
||||
}
|
||||
|
||||
private void execute() throws IOException, ClientProtocolException, UnsupportedEncodingException {
|
||||
ourLog.info("Starting...");
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
@ -85,13 +90,13 @@ public class Uploader {
|
|||
if (nextEntry1.getResource() instanceof SearchParameter) {
|
||||
continue;
|
||||
}
|
||||
bundle.addEntry().setTransaction(new EntryTransaction().setMethod(HTTPVerbEnum.POST)).setResource(nextEntry1.getResource());
|
||||
bundle.addEntry().setRequest(new EntryRequest().setMethod(HTTPVerbEnum.POST)).setResource(nextEntry1.getResource());
|
||||
}
|
||||
} else {
|
||||
if (parsed instanceof SearchParameter) {
|
||||
continue;
|
||||
}
|
||||
bundle.addEntry().setTransaction(new EntryTransaction().setMethod(HTTPVerbEnum.POST)).setResource((IResource) parsed);
|
||||
bundle.addEntry().setRequest(new EntryRequest().setMethod(HTTPVerbEnum.POST)).setResource((IResource) parsed);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -113,10 +118,10 @@ public class Uploader {
|
|||
for (Entry next : bundle.getEntry()) {
|
||||
List<ResourceReferenceInfo> refs = ctx.newTerser().getAllResourceReferences(next.getResource());
|
||||
for (ResourceReferenceInfo nextRef : refs) {
|
||||
// if (nextRef.getResourceReference().getReferenceElement().isAbsolute()) {
|
||||
// ourLog.info("Discarding absolute reference: {}", nextRef.getResourceReference().getReferenceElement().getValue());
|
||||
// nextRef.getResourceReference().getReferenceElement().setValue(null);
|
||||
// }
|
||||
// if (nextRef.getResourceReference().getReferenceElement().isAbsolute()) {
|
||||
// ourLog.info("Discarding absolute reference: {}", nextRef.getResourceReference().getReferenceElement().getValue());
|
||||
// nextRef.getResourceReference().getReferenceElement().setValue(null);
|
||||
// }
|
||||
nextRef.getResourceReference().getReferenceElement().setValue(nextRef.getResourceReference().getReferenceElement().toUnqualifiedVersionless().getValue());
|
||||
String value = nextRef.getResourceReference().getReferenceElement().toUnqualifiedVersionless().getValue();
|
||||
if (!ids.contains(value) && !nextRef.getResourceReference().getReferenceElement().isLocal()) {
|
||||
|
@ -127,13 +132,13 @@ public class Uploader {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for (Entry next : bundle.getEntry()) {
|
||||
// if (next.getResource().getId().hasIdPart() && Character.isLetter(next.getResource().getId().getIdPart().charAt(0))) {
|
||||
// next.getTransaction().setUrl(next.getResource().getResourceName() + '/' + next.getResource().getId().getIdPart());
|
||||
// next.getTransaction().setMethod(HTTPVerbEnum.PUT);
|
||||
// }
|
||||
// }
|
||||
|
||||
// for (Entry next : bundle.getEntry()) {
|
||||
// if (next.getResource().getId().hasIdPart() && Character.isLetter(next.getResource().getId().getIdPart().charAt(0))) {
|
||||
// next.getTransaction().setUrl(next.getResource().getResourceName() + '/' + next.getResource().getId().getIdPart());
|
||||
// next.getTransaction().setMethod(HTTPVerbEnum.PUT);
|
||||
// }
|
||||
// }
|
||||
|
||||
ourLog.info("{} good references", goodRefs);
|
||||
|
||||
|
@ -141,9 +146,8 @@ public class Uploader {
|
|||
ourLog.info("Final bundle: {} entries", bundle.getEntry().size());
|
||||
ourLog.info("Final bundle: {} chars", encoded.length());
|
||||
|
||||
IGenericClient fhirClient = ctx.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu2");
|
||||
IGenericClient fhirClient = newClient(ctx);
|
||||
fhirClient.transaction().withBundle(bundle).execute();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package ca.uhn.fhir.cli;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.hl7.fhir.instance.model.Bundle;
|
||||
import org.hl7.fhir.instance.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.instance.model.StructureDefinition;
|
||||
import org.hl7.fhir.instance.model.ValueSet;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
||||
|
||||
public class ValidationDataUploader extends BaseCommand {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidationDataUploader.class);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new ValidationDataUploader().execute();
|
||||
}
|
||||
|
||||
private void execute() throws IOException, ClientProtocolException, UnsupportedEncodingException {
|
||||
ourLog.info("Starting...");
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu2Hl7Org();
|
||||
|
||||
IGenericClient client = newClient(ctx);
|
||||
|
||||
// String vsContents =
|
||||
// IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/instance/model/valueset/valuesets.xml"),
|
||||
// "UTF-8");
|
||||
// Bundle bundle = ctx.newXmlParser().parseResource(Bundle.class, vsContents);
|
||||
//
|
||||
// int total = bundle.getEntry().size();
|
||||
// int count = 1;
|
||||
// for (BundleEntryComponent i : bundle.getEntry()) {
|
||||
// ValueSet next = (ValueSet) i.getResource();
|
||||
// next.setId(next.getIdElement().toUnqualifiedVersionless());
|
||||
//
|
||||
// ourLog.info("Uploading ValueSet {}/{} : {}", new Object[] {count,total,next.getIdElement().getValue()});
|
||||
// client.update().resource(next).execute();
|
||||
//
|
||||
// count++;
|
||||
// }
|
||||
//
|
||||
// ourLog.info("Finished uploading ValueSets");
|
||||
|
||||
String vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/instance/model/valueset/v3-codesystems.xml"), "UTF-8");
|
||||
Bundle bundle = ctx.newXmlParser().parseResource(Bundle.class, vsContents);
|
||||
|
||||
int total;
|
||||
int count;
|
||||
|
||||
// total = bundle.getEntry().size();
|
||||
// count = 1;
|
||||
// for (BundleEntryComponent i : bundle.getEntry()) {
|
||||
// ValueSet next = (ValueSet) i.getResource();
|
||||
// next.setId(next.getIdElement().toUnqualifiedVersionless());
|
||||
//
|
||||
// ourLog.info("Uploading v3-codesystems ValueSet {}/{} : {}", new Object[] { count, total, next.getIdElement().getValue() });
|
||||
// client.update().resource(next).execute();
|
||||
//
|
||||
// count++;
|
||||
// }
|
||||
|
||||
ourLog.info("Finished uploading ValueSets");
|
||||
|
||||
ResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
|
||||
Resource[] mappingLocations = patternResolver.getResources("classpath*:org/hl7/fhir/instance/model/profile/*.profile.xml");
|
||||
total = mappingLocations.length;
|
||||
count = 1;
|
||||
for (Resource i : mappingLocations) {
|
||||
StructureDefinition next = ctx.newXmlParser().parseResource(StructureDefinition.class, IOUtils.toString(i.getInputStream(), "UTF-8"));
|
||||
next.setId(next.getIdElement().toUnqualifiedVersionless());
|
||||
|
||||
ourLog.info("Uploading StructureDefinition {}/{} : {}", new Object[] { count, total, next.getIdElement().getValue() });
|
||||
client.update().resource(next).execute();
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
ourLog.info("Finished uploading ValueSets");
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -36,6 +36,11 @@
|
|||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-jpaserver-base</artifactId>
|
||||
|
@ -45,24 +50,17 @@
|
|||
<dependency>
|
||||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-schematron</artifactId>
|
||||
<version>${phloc_schematron_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-commons</artifactId>
|
||||
<version>${phloc_commons_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf</artifactId>
|
||||
<version>${thymeleaf-version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
Use an older version of SLF4j just to make sure we compile correctly
|
||||
against old SLF4j - Some people can't upgrade and we have no real
|
||||
need for recent features.
|
||||
-->
|
||||
<!-- Use an older version of SLF4j just to make sure we compile correctly against old SLF4j - Some people can't upgrade and we have no real need for recent features. -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
|
@ -146,18 +144,15 @@
|
|||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ebaysf.web</groupId>
|
||||
<artifactId>cors-filter</artifactId>
|
||||
<version>${ebay_cors_filter_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>xmlunit</groupId>
|
||||
<artifactId>xmlunit</artifactId>
|
||||
<version>${xmlunit_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -176,36 +171,10 @@
|
|||
<skipDeploy>true</skipDeploy>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>false</skip>
|
||||
<formats>
|
||||
<format>html</format>
|
||||
<format>xml</format>
|
||||
</formats>
|
||||
<maxmem>256m</maxmem>
|
||||
<instrumentation>
|
||||
<ignores>
|
||||
<ignore>ca.uhn.fhir.model.dstu.valueset.*</ignore>
|
||||
</ignores>
|
||||
<excludes>
|
||||
<ignore>**/valueset/*.class</ignore>
|
||||
<ignore>**/exceptions/*.class</ignore>
|
||||
</excludes>
|
||||
<!-- <ignoreMethodAnnotations> <ignoreMethodAnnotation>net.sourceforge.cobertura.CoverageIgnore</ignoreMethodAnnotation> </ignoreMethodAnnotations> -->
|
||||
</instrumentation>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>cobertura-maven-plugin</artifactId> <configuration> <skip>false</skip> <formats> <format>html</format> <format>xml</format> </formats>
|
||||
<maxmem>256m</maxmem> <instrumentation> <ignores> <ignore>ca.uhn.fhir.model.dstu.valueset.*</ignore> </ignores> <excludes> <ignore>**/valueset/*.class</ignore> <ignore>**/exceptions/*.class</ignore> </excludes>
|
||||
</instrumentation> </configuration> <executions> <execution> <phase>verify</phase> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> -->
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
|
@ -214,11 +183,6 @@
|
|||
<artifactId>coveralls-maven-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<coberturaReports>
|
||||
<coberturaReport>
|
||||
${basedir}/target/coverage.xml
|
||||
</coberturaReport>
|
||||
</coberturaReports>
|
||||
<sourceEncoding>UTF-8</sourceEncoding>
|
||||
<serviceName>travis-ci</serviceName>
|
||||
<serviceJobId>${env.TRAVIS_JOB_ID}</serviceJobId>
|
||||
|
@ -272,7 +236,7 @@
|
|||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<runOrder>alphabetical</runOrder>
|
||||
<argLine>-Xms512m -Xmx1024m</argLine>
|
||||
<argLine>-Xms512m -Xmx1024m ${argLine}</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
@ -291,26 +255,25 @@
|
|||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<check>
|
||||
<haltOnFailure>true</haltOnFailure>
|
||||
</check>
|
||||
</configuration>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.7.5.201505241946</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>verify</phase>
|
||||
<id>prepare-agent</id>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>jacoco-site</id>
|
||||
<phase>post-integration-test</phase>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>cobertura-maven-plugin</artifactId> <version>${maven_cobertura_plugin_version}</version> <configuration> <check> <branchRate>85</branchRate>
|
||||
<lineRate>85</lineRate> <haltOnFailure>true</haltOnFailure> <totalBranchRate>85</totalBranchRate> <totalLineRate>85</totalLineRate> <packageLineRate>85</packageLineRate> <packageBranchRate>85</packageBranchRate>
|
||||
<regexes> <regex> <pattern>com.example.reallyimportant.*</pattern> <branchRate>90</branchRate> <lineRate>80</lineRate> </regex> <regex> <pattern>com.example.boringcode.*</pattern> <branchRate>40</branchRate>
|
||||
<lineRate>30</lineRate> </regex> </regexes> </check> </configuration> <executions> <execution> <goals> <goal>clean</goal> <goal>check</goal> </goals> </execution> </executions> </plugin> -->
|
||||
</plugins>
|
||||
<resources>
|
||||
</resources>
|
||||
|
@ -331,22 +294,6 @@
|
|||
</build>
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<reportSets>
|
||||
<reportSet>
|
||||
<reports>
|
||||
<report>cobertura</report>
|
||||
</reports>
|
||||
<configuration>
|
||||
<check>
|
||||
<haltOnFailure>true</haltOnFailure>
|
||||
</check>
|
||||
</configuration>
|
||||
</reportSet>
|
||||
</reportSets>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||
|
|
|
@ -0,0 +1,378 @@
|
|||
<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>
|
||||
|
||||
<!-- The parent of this project is the deployable POM. This project isn't deployable, but this keeps it before the root pom in the reactor order when building the site. I don't know why this works...
|
||||
Need to investigate this. -->
|
||||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-cobertura</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>HAPI FHIR - Cobertura Test Coverage</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-jpaserver-base</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-schematron</artifactId>
|
||||
<version>${phloc_schematron_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-commons</artifactId>
|
||||
<version>${phloc_commons_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf</artifactId>
|
||||
<version>${thymeleaf-version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
Use an older version of SLF4j just to make sure we compile correctly
|
||||
against old SLF4j - Some people can't upgrade and we have no real
|
||||
need for recent features.
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.6.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Test Database -->
|
||||
<dependency>
|
||||
<groupId>org.apache.derby</groupId>
|
||||
<artifactId>derby</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-dbcp2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlets</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-util</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.json-lib</groupId>
|
||||
<artifactId>json-lib</artifactId>
|
||||
<version>2.4</version>
|
||||
<classifier>jdk15</classifier>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.json-lib</groupId>
|
||||
<artifactId>json-lib</artifactId>
|
||||
<version>2.4</version>
|
||||
<classifier>jdk15-sources</classifier>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>directory-naming</groupId>
|
||||
<artifactId>naming-java</artifactId>
|
||||
<version>0.8</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ebaysf.web</groupId>
|
||||
<artifactId>cors-filter</artifactId>
|
||||
<version>${ebay_cors_filter_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>xmlunit</groupId>
|
||||
<artifactId>xmlunit</artifactId>
|
||||
<version>${xmlunit_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-site-plugin</artifactId>
|
||||
<configuration>
|
||||
<skipDeploy>true</skipDeploy>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>false</skip>
|
||||
<formats>
|
||||
<format>html</format>
|
||||
<format>xml</format>
|
||||
</formats>
|
||||
<maxmem>256m</maxmem>
|
||||
<instrumentation>
|
||||
<ignores>
|
||||
<ignore>ca.uhn.fhir.model.dstu.valueset.*</ignore>
|
||||
</ignores>
|
||||
<excludes>
|
||||
<ignore>**/valueset/*.class</ignore>
|
||||
<ignore>**/exceptions/*.class</ignore>
|
||||
</excludes>
|
||||
<!-- <ignoreMethodAnnotations> <ignoreMethodAnnotation>net.sourceforge.cobertura.CoverageIgnore</ignoreMethodAnnotation> </ignoreMethodAnnotations> -->
|
||||
</instrumentation>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.eluder.coveralls</groupId>
|
||||
<artifactId>coveralls-maven-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<coberturaReports>
|
||||
<coberturaReport>
|
||||
${basedir}/target/coverage.xml
|
||||
</coberturaReport>
|
||||
</coberturaReports>
|
||||
<sourceEncoding>UTF-8</sourceEncoding>
|
||||
<serviceName>travis-ci</serviceName>
|
||||
<serviceJobId>${env.TRAVIS_JOB_ID}</serviceJobId>
|
||||
<sourceDirectories>
|
||||
<sourceDirectory>../hapi-fhir-structures-dstu/src/test/java</sourceDirectory>
|
||||
<sourceDirectory>../hapi-fhir-structures-dstu2/src/test/java</sourceDirectory>
|
||||
<sourceDirectory>../hapi-fhir-structures-hl7org-dstu2/src/test/java</sourceDirectory>
|
||||
<sourceDirectory>../hapi-fhir-jpaserver-base/src/test/java</sourceDirectory>
|
||||
<sourceDirectory>../hapi-fhir-base/src/main/java</sourceDirectory>
|
||||
<sourceDirectory>../hapi-fhir-jpaserver-base/src/main/java</sourceDirectory>
|
||||
</sourceDirectories>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<version>${maven_build_helper_plugin_version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-source</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>../hapi-fhir-base/src/main/java</source>
|
||||
<source>../hapi-fhir-jpaserver-base/src/main/java</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>add-test-source</id>
|
||||
<phase>generate-test-sources</phase>
|
||||
<goals>
|
||||
<goal>add-test-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>../hapi-fhir-structures-dstu/src/test/java</source>
|
||||
<source>../hapi-fhir-structures-dstu2/src/test/java</source>
|
||||
<source>../hapi-fhir-structures-hl7org-dstu2/src/test/java</source>
|
||||
<source>../hapi-fhir-jpaserver-base/src/test/java</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<runOrder>alphabetical</runOrder>
|
||||
<argLine>-Xms512m -Xmx1024m</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-install-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<check>
|
||||
<haltOnFailure>true</haltOnFailure>
|
||||
</check>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>cobertura-maven-plugin</artifactId> <version>${maven_cobertura_plugin_version}</version> <configuration> <check> <branchRate>85</branchRate>
|
||||
<lineRate>85</lineRate> <haltOnFailure>true</haltOnFailure> <totalBranchRate>85</totalBranchRate> <totalLineRate>85</totalLineRate> <packageLineRate>85</packageLineRate> <packageBranchRate>85</packageBranchRate>
|
||||
<regexes> <regex> <pattern>com.example.reallyimportant.*</pattern> <branchRate>90</branchRate> <lineRate>80</lineRate> </regex> <regex> <pattern>com.example.boringcode.*</pattern> <branchRate>40</branchRate>
|
||||
<lineRate>30</lineRate> </regex> </regexes> </check> </configuration> <executions> <execution> <goals> <goal>clean</goal> <goal>check</goal> </goals> </execution> </executions> </plugin> -->
|
||||
</plugins>
|
||||
<resources>
|
||||
</resources>
|
||||
<testResources>
|
||||
<testResource>
|
||||
<directory>../hapi-fhir-jpaserver-base/src/test/resources</directory>
|
||||
</testResource>
|
||||
<testResource>
|
||||
<directory>../hapi-fhir-structures-dstu/src/test/resources</directory>
|
||||
</testResource>
|
||||
<testResource>
|
||||
<directory>../hapi-fhir-structures-dstu2/src/test/resources</directory>
|
||||
</testResource>
|
||||
<testResource>
|
||||
<directory>../hapi-fhir-structures-hl7org-dstu2/src/test/resources</directory>
|
||||
</testResource>
|
||||
</testResources>
|
||||
</build>
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<reportSets>
|
||||
<reportSet>
|
||||
<reports>
|
||||
<report>cobertura</report>
|
||||
</reports>
|
||||
<configuration>
|
||||
<check>
|
||||
<haltOnFailure>true</haltOnFailure>
|
||||
</check>
|
||||
</configuration>
|
||||
</reportSet>
|
||||
</reportSets>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||
<version>${maven_project_info_plugin_version}</version>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>TRAVIS</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- Travis build seems to run out of memory unless we don't reuse JVMs -->
|
||||
<reuseForks>false</reuseForks>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -33,27 +33,22 @@
|
|||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ebaysf.web</groupId>
|
||||
<artifactId>cors-filter</artifactId>
|
||||
<version>${ebay_cors_filter_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf</artifactId>
|
||||
<version>${thymeleaf-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-schematron</artifactId>
|
||||
<version>${phloc_schematron_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-commons</artifactId>
|
||||
<version>${phloc_commons_version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -76,7 +71,6 @@
|
|||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>${maven_assembly_plugin_version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
update hfj_resource set forced_id_pid = null where res_id in (select res_id from hfj_resource where sp_index_status = 2);
|
||||
delete from hfj_history_tag where res_id in (select res_id from hfj_resource where sp_index_status = 2);
|
||||
delete from hfj_res_ver where res_id in (select res_id from hfj_resource where sp_index_status = 2);
|
||||
delete from hfj_forced_id where resource_pid in (select res_id from hfj_resource where sp_index_status = 2);
|
||||
delete from hfj_spidx_date where res_id in (select res_id from hfj_resource where sp_index_status = 2);
|
||||
delete from hfj_spidx_number where res_id in (select res_id from hfj_resource where sp_index_status = 2);
|
||||
delete from hfj_spidx_quantity where res_id in (select res_id from hfj_resource where sp_index_status = 2);
|
||||
delete from hfj_spidx_string where res_id in (select res_id from hfj_resource where sp_index_status = 2);
|
||||
delete from hfj_spidx_token where res_id in (select res_id from hfj_resource where sp_index_status = 2);
|
||||
delete from hfj_res_link where src_resource_id in (select res_id from hfj_resource where sp_index_status = 2);
|
||||
delete from hfj_res_tag where res_id in (select res_id from hfj_resource where sp_index_status = 2);
|
||||
delete from hfj_resource where res_id in (select res_id from hfj_resource where sp_index_status = 2);
|
||||
|
|
@ -43,25 +43,26 @@
|
|||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources</artifactId>
|
||||
<version>1.2-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>${slf4j_version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -242,7 +243,6 @@
|
|||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava_version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -265,6 +265,11 @@
|
|||
<artifactId>jetty-util</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -117,6 +117,8 @@ import ca.uhn.fhir.util.FhirTerser;
|
|||
|
||||
public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||
|
||||
public static final long INDEX_STATUS_INDEXED = Long.valueOf(1L);
|
||||
public static final long INDEX_STATUS_INDEXING_FAILED = Long.valueOf(2L);
|
||||
public static final String NS_JPA_PROFILE = "https://github.com/jamesagnew/hapi-fhir/ns/jpa/profile";
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiFhirDao.class);
|
||||
|
||||
|
@ -1127,12 +1129,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
entity.setParamsDatePopulated(dateParams.isEmpty() == false);
|
||||
entity.setResourceLinks(links);
|
||||
entity.setHasLinks(links.isEmpty() == false);
|
||||
entity.setIndexStatus(INDEX_STATUS_INDEXED);
|
||||
|
||||
} else {
|
||||
|
||||
populateResourceIntoEntity(theResource, entity);
|
||||
entity.setUpdated(new Date());
|
||||
entity.setLanguage(theResource.getLanguage().getValue());
|
||||
entity.setIndexStatus(null);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1697,13 +1697,17 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
}
|
||||
|
||||
/**
|
||||
* May be implemented by subclasses to validate resources prior to storage
|
||||
* May be overridden by subclasses to validate resources prior to storage
|
||||
*
|
||||
* @param theResource
|
||||
* The resource that is about to be stored
|
||||
*/
|
||||
protected void preProcessResourceForStorage(T theResource) {
|
||||
// nothing by default
|
||||
if (theResource.getId().hasIdPart()) {
|
||||
if (!theResource.getId().isIdPartValid()) {
|
||||
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "failedToCreateWithInvalidId", theResource.getId().getIdPart()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2303,7 +2307,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
try {
|
||||
entity = readEntityLatestVersion(resourceId);
|
||||
} catch (ResourceNotFoundException e) {
|
||||
if (Character.isDigit(theResource.getId().getIdPart().charAt(0))) {
|
||||
if (resourceId.isIdPartValidLong()) {
|
||||
throw new InvalidRequestException(getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "failedToCreateWithClientAssignedNumericId", theResource.getId().getIdPart()));
|
||||
}
|
||||
return doCreate(theResource, null, thePerformIndexing);
|
||||
|
|
|
@ -22,34 +22,50 @@ package ca.uhn.fhir.jpa.dao;
|
|||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.Query;
|
||||
import javax.persistence.Tuple;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.util.StopWatch;
|
||||
import ca.uhn.fhir.model.api.TagList;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
||||
|
||||
public abstract class BaseHapiFhirSystemDao<T> extends BaseHapiFhirDao implements IFhirSystemDao<T> {
|
||||
public abstract class BaseHapiFhirSystemDao<T> extends BaseHapiFhirDao<IBaseResource>implements IFhirSystemDao<T> {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiFhirSystemDao.class);
|
||||
|
||||
@Transactional(propagation=Propagation.REQUIRED)
|
||||
@PersistenceContext()
|
||||
protected EntityManager myEntityManager;
|
||||
|
||||
@Autowired
|
||||
private PlatformTransactionManager myTxManager;
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
@Override
|
||||
public void deleteAllTagsOnServer() {
|
||||
// Notify interceptors
|
||||
|
@ -59,40 +75,6 @@ public abstract class BaseHapiFhirSystemDao<T> extends BaseHapiFhirDao implement
|
|||
myEntityManager.createQuery("DELETE from ResourceTag t").executeUpdate();
|
||||
}
|
||||
|
||||
@PersistenceContext()
|
||||
protected EntityManager myEntityManager;
|
||||
|
||||
protected boolean hasValue(InstantDt theInstantDt) {
|
||||
return theInstantDt != null && theInstantDt.isEmpty() == false;
|
||||
}
|
||||
|
||||
protected ResourceTable tryToLoadEntity(IdDt nextId) {
|
||||
ResourceTable entity;
|
||||
try {
|
||||
Long pid = translateForcedIdToPid(nextId);
|
||||
entity = myEntityManager.find(ResourceTable.class, pid);
|
||||
} catch (ResourceNotFoundException e) {
|
||||
entity = null;
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
protected ResourceTable loadFirstEntityFromCandidateMatches(Set<Long> candidateMatches) {
|
||||
return myEntityManager.find(ResourceTable.class, candidateMatches.iterator().next());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider history(Date theSince) {
|
||||
// Notify interceptors
|
||||
ActionRequestDetails requestDetails = new ActionRequestDetails(null, null);
|
||||
notifyInterceptors(RestOperationTypeEnum.HISTORY_SYSTEM, requestDetails);
|
||||
|
||||
StopWatch w = new StopWatch();
|
||||
IBundleProvider retVal = super.history(null, null, theSince);
|
||||
ourLog.info("Processed global history in {}ms", w.getMillisAndRestart());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TagList getAllTags() {
|
||||
// Notify interceptors
|
||||
|
@ -124,4 +106,122 @@ public abstract class BaseHapiFhirSystemDao<T> extends BaseHapiFhirDao implement
|
|||
return retVal;
|
||||
}
|
||||
|
||||
protected boolean hasValue(InstantDt theInstantDt) {
|
||||
return theInstantDt != null && theInstantDt.isEmpty() == false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider history(Date theSince) {
|
||||
// Notify interceptors
|
||||
ActionRequestDetails requestDetails = new ActionRequestDetails(null, null);
|
||||
notifyInterceptors(RestOperationTypeEnum.HISTORY_SYSTEM, requestDetails);
|
||||
|
||||
StopWatch w = new StopWatch();
|
||||
IBundleProvider retVal = super.history(null, null, theSince);
|
||||
ourLog.info("Processed global history in {}ms", w.getMillisAndRestart());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
protected ResourceTable loadFirstEntityFromCandidateMatches(Set<Long> candidateMatches) {
|
||||
return myEntityManager.find(ResourceTable.class, candidateMatches.iterator().next());
|
||||
}
|
||||
|
||||
@Transactional()
|
||||
@Override
|
||||
public int markAllResourcesForReindexing() {
|
||||
return myEntityManager.createQuery("UPDATE " + ResourceTable.class.getSimpleName() + " t SET t.myIndexStatus = null").executeUpdate();
|
||||
}
|
||||
|
||||
private void markResourceAsIndexingFailed(final ResourceTable theResourceTable) {
|
||||
ourLog.info("Marking resource with PID {} and ID {} as indexing_failed", new Object[] { theResourceTable.getId(), theResourceTable.getIdDt().getValue() });
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(myTxManager);
|
||||
txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
|
||||
txTemplate.execute(new TransactionCallback<Void>() {
|
||||
@Override
|
||||
public Void doInTransaction(TransactionStatus theStatus) {
|
||||
Query q = myEntityManager.createQuery("UPDATE ResourceTable t SET t.myIndexStatus = :status WHERE t.myId = :id");
|
||||
q.setParameter("status", INDEX_STATUS_INDEXING_FAILED);
|
||||
q.setParameter("id", theResourceTable.getId());
|
||||
q.executeUpdate();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
@Transactional()
|
||||
public int performReindexingPass(Integer theCount) {
|
||||
TypedQuery<ResourceTable> q = myEntityManager.createQuery("SELECT t FROM " + ResourceTable.class.getSimpleName() + " t WHERE t.myIndexStatus IS null", ResourceTable.class);
|
||||
|
||||
int maxResult = 500;
|
||||
if (theCount != null) {
|
||||
maxResult = Math.min(theCount, 2000);
|
||||
}
|
||||
|
||||
q.setMaxResults(maxResult);
|
||||
List<ResourceTable> resources = q.getResultList();
|
||||
|
||||
ourLog.info("Indexing {} resources", resources.size());
|
||||
|
||||
int count = 0;
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
for (ResourceTable resourceTable : resources) {
|
||||
final IBaseResource resource;
|
||||
try {
|
||||
resource = toResource(resourceTable);
|
||||
} catch (DataFormatException e) {
|
||||
ourLog.warn("Failure parsing resource: {}", e.toString());
|
||||
markResourceAsIndexingFailed(resourceTable);
|
||||
continue;
|
||||
}
|
||||
@SuppressWarnings("rawtypes")
|
||||
final IFhirResourceDao dao = getDao(resource.getClass());
|
||||
if (dao == null) {
|
||||
ourLog.warn("No DAO for type: {}", resource.getClass());
|
||||
markResourceAsIndexingFailed(resourceTable);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (resource.getIdElement().isIdPartValid() == false) {
|
||||
ourLog.warn("Not going to try and index an invalid ID: {}", resource.getIdElement());
|
||||
markResourceAsIndexingFailed(resourceTable);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(myTxManager);
|
||||
txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
|
||||
txTemplate.execute(new TransactionCallback<Void>() {
|
||||
@Override
|
||||
public Void doInTransaction(TransactionStatus theStatus) {
|
||||
dao.update(resource, null, true);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
ourLog.error("Failed to index resource {}: {}", new Object[] { resource.getIdElement(), e.toString() });
|
||||
markResourceAsIndexingFailed(resourceTable);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
long delay = System.currentTimeMillis() - start;
|
||||
ourLog.info("Indexed {} / {} resources in {}ms", new Object[] { count, resources.size(), delay });
|
||||
|
||||
return resources.size();
|
||||
}
|
||||
|
||||
protected ResourceTable tryToLoadEntity(IdDt nextId) {
|
||||
ResourceTable entity;
|
||||
try {
|
||||
Long pid = translateForcedIdToPid(nextId);
|
||||
entity = myEntityManager.find(ResourceTable.class, pid);
|
||||
} catch (ResourceNotFoundException e) {
|
||||
entity = null;
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,26 +28,36 @@ import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
|||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
|
||||
/**
|
||||
* @param <T> The bundle type
|
||||
* @param <T>
|
||||
* The bundle type
|
||||
*/
|
||||
public interface IFhirSystemDao<T> extends IDao {
|
||||
|
||||
T transaction(T theResources);
|
||||
|
||||
IBundleProvider history(Date theDate);
|
||||
|
||||
TagList getAllTags();
|
||||
|
||||
Map<String, Long> getResourceCounts();
|
||||
|
||||
/**
|
||||
* Not supported for DSTU1
|
||||
*/
|
||||
MetaDt metaGetOperation();
|
||||
|
||||
/**
|
||||
* Use with caution! This deletes everything!!
|
||||
*/
|
||||
void deleteAllTagsOnServer();
|
||||
|
||||
TagList getAllTags();
|
||||
|
||||
Map<String, Long> getResourceCounts();
|
||||
|
||||
IBundleProvider history(Date theDate);
|
||||
|
||||
int performReindexingPass(Integer theCount);
|
||||
|
||||
/**
|
||||
* Marks all indexes as needing fresh indexing
|
||||
*
|
||||
* @return Returns the number of affected rows
|
||||
*/
|
||||
int markAllResourcesForReindexing();
|
||||
|
||||
/**
|
||||
* Not supported for DSTU1
|
||||
*/
|
||||
MetaDt metaGetOperation();
|
||||
|
||||
T transaction(T theResources);
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import javax.measure.quantity.Quantity;
|
|||
import javax.measure.unit.NonSI;
|
||||
import javax.measure.unit.Unit;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
|
@ -60,6 +61,7 @@ import ca.uhn.fhir.model.dstu2.composite.IdentifierDt;
|
|||
import ca.uhn.fhir.model.dstu2.composite.PeriodDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.QuantityDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Conformance.RestSecurity;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Location;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient.Communication;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Questionnaire;
|
||||
|
@ -73,6 +75,8 @@ import ca.uhn.fhir.rest.method.RestSearchParameterTypeEnum;
|
|||
|
||||
public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implements ISearchParamExtractor {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchParamExtractorDstu2.class);
|
||||
|
||||
public SearchParamExtractorDstu2(FhirContext theContext) {
|
||||
super(theContext);
|
||||
}
|
||||
|
@ -80,8 +84,7 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamDates(ca.uhn.fhir.jpa.entity.ResourceTable,
|
||||
* ca.uhn.fhir.model.api.IResource)
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamDates(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource)
|
||||
*/
|
||||
@Override
|
||||
public List<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource) {
|
||||
|
@ -143,8 +146,7 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamNumber(ca.uhn.fhir.jpa.entity.ResourceTable,
|
||||
* ca.uhn.fhir.model.api.IResource)
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamNumber(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource)
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource) {
|
||||
|
@ -191,18 +193,12 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
nextValue = newValue;
|
||||
|
||||
/*
|
||||
* @SuppressWarnings("unchecked") PhysicsUnit<? extends
|
||||
* org.unitsofmeasurement.quantity.Quantity<?>> unit = (PhysicsUnit<? extends
|
||||
* org.unitsofmeasurement.quantity.Quantity<?>>)
|
||||
* UCUMFormat.getCaseInsensitiveInstance().parse(nextValue.getCode().getValue(), null); if
|
||||
* (unit.isCompatible(UCUM.DAY)) {
|
||||
* @SuppressWarnings("unchecked") PhysicsUnit<? extends org.unitsofmeasurement.quantity.Quantity<?>> unit = (PhysicsUnit<? extends org.unitsofmeasurement.quantity.Quantity<?>>)
|
||||
* UCUMFormat.getCaseInsensitiveInstance().parse(nextValue.getCode().getValue(), null); if (unit.isCompatible(UCUM.DAY)) {
|
||||
*
|
||||
* @SuppressWarnings("unchecked") PhysicsUnit<org.unitsofmeasurement.quantity.Time> timeUnit
|
||||
* = (PhysicsUnit<Time>) unit; UnitConverter conv = timeUnit.getConverterTo(UCUM.DAY);
|
||||
* double dayValue = conv.convert(nextValue.getValue().getValue().doubleValue()); DurationDt
|
||||
* newValue = new DurationDt(); newValue.setSystem(UCUM_NS);
|
||||
* newValue.setCode(UCUM.DAY.getSymbol()); newValue.setValue(dayValue); nextValue=newValue;
|
||||
* }
|
||||
* @SuppressWarnings("unchecked") PhysicsUnit<org.unitsofmeasurement.quantity.Time> timeUnit = (PhysicsUnit<Time>) unit; UnitConverter conv = timeUnit.getConverterTo(UCUM.DAY);
|
||||
* double dayValue = conv.convert(nextValue.getValue().getValue().doubleValue()); DurationDt newValue = new DurationDt(); newValue.setSystem(UCUM_NS);
|
||||
* newValue.setCode(UCUM.DAY.getSymbol()); newValue.setValue(dayValue); nextValue=newValue; }
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -246,8 +242,7 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamQuantity(ca.uhn.fhir.jpa.entity.ResourceTable,
|
||||
* ca.uhn.fhir.model.api.IResource)
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamQuantity(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource)
|
||||
*/
|
||||
@Override
|
||||
public List<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) {
|
||||
|
@ -281,7 +276,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
continue;
|
||||
}
|
||||
|
||||
ResourceIndexedSearchParamQuantity nextEntity = new ResourceIndexedSearchParamQuantity(resourceName, nextValue.getValueElement().getValue(), nextValue.getSystemElement().getValueAsString(), nextValue.getCode());
|
||||
ResourceIndexedSearchParamQuantity nextEntity = new ResourceIndexedSearchParamQuantity(resourceName, nextValue.getValueElement().getValue(),
|
||||
nextValue.getSystemElement().getValueAsString(), nextValue.getCode());
|
||||
nextEntity.setResource(theEntity);
|
||||
retVal.add(nextEntity);
|
||||
} else {
|
||||
|
@ -302,8 +298,7 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamStrings(ca.uhn.fhir.jpa.entity.ResourceTable,
|
||||
* ca.uhn.fhir.model.api.IResource)
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamStrings(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource)
|
||||
*/
|
||||
@Override
|
||||
public List<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource) {
|
||||
|
@ -317,11 +312,11 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
|
||||
String nextPath = nextSpDef.getPath();
|
||||
String resourceName = nextSpDef.getName();
|
||||
|
||||
|
||||
if (isBlank(nextPath)) {
|
||||
|
||||
|
||||
// TODO: implement phonetic, and any others that have no path
|
||||
|
||||
|
||||
if ("Questionnaire".equals(def.getName()) && nextSpDef.getName().equals("title")) {
|
||||
Questionnaire q = (Questionnaire) theResource;
|
||||
String title = q.getGroup().getTitle();
|
||||
|
@ -399,8 +394,7 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamTokens(ca.uhn.fhir.jpa.entity.ResourceTable,
|
||||
* ca.uhn.fhir.model.api.IResource)
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamTokens(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource)
|
||||
*/
|
||||
@Override
|
||||
public List<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource) {
|
||||
|
@ -411,7 +405,7 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
ValueSet vs = (ValueSet) theResource;
|
||||
useSystem = vs.getCodeSystem().getSystem();
|
||||
}
|
||||
|
||||
|
||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
||||
if (nextSpDef.getParamType() != RestSearchParameterTypeEnum.TOKEN) {
|
||||
|
@ -442,32 +436,41 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
}
|
||||
|
||||
for (Object nextObject : extractValues(nextPath, theResource)) {
|
||||
|
||||
// Patient:language
|
||||
|
||||
// Patient:language
|
||||
if (nextObject instanceof Patient.Communication) {
|
||||
Communication nextValue = (Patient.Communication) nextObject;
|
||||
nextObject= nextValue.getLanguage();
|
||||
nextObject = nextValue.getLanguage();
|
||||
}
|
||||
|
||||
|
||||
if (nextObject instanceof IdentifierDt) {
|
||||
IdentifierDt nextValue = (IdentifierDt) nextObject;
|
||||
if (nextValue.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
systems.add(nextValue.getSystemElement().getValueAsString());
|
||||
codes.add(nextValue.getValueElement().getValue());
|
||||
String system = StringUtils.defaultIfBlank(nextValue.getSystemElement().getValueAsString(), null);
|
||||
String value = nextValue.getValueElement().getValue();
|
||||
if (isNotBlank(value)) {
|
||||
systems.add(system);
|
||||
codes.add(value);
|
||||
}
|
||||
|
||||
if (isNotBlank(nextValue.getType().getText())) {
|
||||
addStringParam(theEntity, retVal, nextSpDef, nextValue.getType().getText());
|
||||
}
|
||||
|
||||
} else if (nextObject instanceof ContactPointDt) {
|
||||
ContactPointDt nextValue = (ContactPointDt) nextObject;
|
||||
if (nextValue.isEmpty()) {
|
||||
ContactPointDt nextValue = (ContactPointDt) nextObject;
|
||||
if (nextValue.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (isNotBlank(needContactPointSystem)) {
|
||||
if (!needContactPointSystem.equals(nextValue.getSystemElement().getValueAsString())) {
|
||||
continue;
|
||||
}
|
||||
if (isNotBlank(needContactPointSystem)) {
|
||||
if (!needContactPointSystem.equals(nextValue.getSystemElement().getValueAsString())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
systems.add(nextValue.getSystemElement().getValueAsString());
|
||||
codes.add(nextValue.getValueElement().getValue());
|
||||
}
|
||||
systems.add(nextValue.getSystemElement().getValueAsString());
|
||||
codes.add(nextValue.getValueElement().getValue());
|
||||
} else if (nextObject instanceof IPrimitiveDatatype<?>) {
|
||||
IPrimitiveDatatype<?> nextValue = (IPrimitiveDatatype<?>) nextObject;
|
||||
if (nextValue.isEmpty()) {
|
||||
|
@ -481,39 +484,23 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
codes.add(nextValue.getValueAsString());
|
||||
} else if (nextObject instanceof CodingDt) {
|
||||
CodingDt nextValue = (CodingDt) nextObject;
|
||||
if (nextValue.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String nextSystem = nextValue.getSystemElement().getValueAsString();
|
||||
String nextCode = nextValue.getCodeElement().getValue();
|
||||
if (isNotBlank(nextSystem) || isNotBlank(nextCode)) {
|
||||
systems.add(nextSystem);
|
||||
codes.add(nextCode);
|
||||
}
|
||||
|
||||
if (!nextValue.getDisplayElement().isEmpty()) {
|
||||
systems.add(null);
|
||||
codes.add(nextValue.getDisplayElement().getValue());
|
||||
}
|
||||
extractTokensFromCoding(systems, codes, theEntity, retVal, nextSpDef, nextValue);
|
||||
} else if (nextObject instanceof CodeableConceptDt) {
|
||||
CodeableConceptDt nextCC = (CodeableConceptDt) nextObject;
|
||||
if (!nextCC.getTextElement().isEmpty()) {
|
||||
String value = nextCC.getTextElement().getValue();
|
||||
if (value.length() > ResourceIndexedSearchParamString.MAX_LENGTH) {
|
||||
value = value.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
|
||||
}
|
||||
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(nextSpDef.getName(), BaseHapiFhirDao.normalizeString(value), value);
|
||||
nextEntity.setResource(theEntity);
|
||||
retVal.add(nextEntity);
|
||||
addStringParam(theEntity, retVal, nextSpDef, nextCC.getTextElement().getValue());
|
||||
}
|
||||
|
||||
extractTokensFromCodeableConcept(systems, codes, nextCC);
|
||||
extractTokensFromCodeableConcept(systems, codes, nextCC, theEntity, retVal, nextSpDef);
|
||||
} else if (nextObject instanceof RestSecurity) {
|
||||
// Conformance.security search param points to something kind of useless right now - This should probably be fixed.
|
||||
RestSecurity sec = (RestSecurity)nextObject;
|
||||
RestSecurity sec = (RestSecurity) nextObject;
|
||||
for (BoundCodeableConceptDt<RestfulSecurityServiceEnum> nextCC : sec.getService()) {
|
||||
extractTokensFromCodeableConcept(systems, codes, nextCC);
|
||||
extractTokensFromCodeableConcept(systems, codes, nextCC, theEntity, retVal, nextSpDef);
|
||||
}
|
||||
} else if (nextObject instanceof Location.Position) {
|
||||
ourLog.warn("Position search not currently supported, not indexing location");
|
||||
continue;
|
||||
} else {
|
||||
if (!multiType) {
|
||||
throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
|
||||
|
@ -560,22 +547,35 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
|
|||
return retVal;
|
||||
}
|
||||
|
||||
private void extractTokensFromCodeableConcept(List<String> systems, List<String> codes, CodeableConceptDt nextCC) {
|
||||
for (CodingDt nextCoding : nextCC.getCoding()) {
|
||||
if (nextCoding.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
private void addStringParam(ResourceTable theEntity, ArrayList<BaseResourceIndexedSearchParam> retVal, RuntimeSearchParam nextSpDef, String value) {
|
||||
if (value.length() > ResourceIndexedSearchParamString.MAX_LENGTH) {
|
||||
value = value.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH);
|
||||
}
|
||||
ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(nextSpDef.getName(), BaseHapiFhirDao.normalizeString(value), value);
|
||||
nextEntity.setResource(theEntity);
|
||||
retVal.add(nextEntity);
|
||||
}
|
||||
|
||||
private void extractTokensFromCodeableConcept(List<String> theSystems, List<String> theCodes, CodeableConceptDt theCodeableConcept, ResourceTable theEntity,
|
||||
ArrayList<BaseResourceIndexedSearchParam> theListToPopulate, RuntimeSearchParam theParameterDef) {
|
||||
for (CodingDt nextCoding : theCodeableConcept.getCoding()) {
|
||||
extractTokensFromCoding(theSystems, theCodes, theEntity, theListToPopulate, theParameterDef, nextCoding);
|
||||
}
|
||||
}
|
||||
|
||||
private void extractTokensFromCoding(List<String> theSystems, List<String> theCodes, ResourceTable theEntity, ArrayList<BaseResourceIndexedSearchParam> theListToPopulate,
|
||||
RuntimeSearchParam theParameterDef, CodingDt nextCoding) {
|
||||
if (nextCoding != null && !nextCoding.isEmpty()) {
|
||||
|
||||
String nextSystem = nextCoding.getSystemElement().getValueAsString();
|
||||
String nextCode = nextCoding.getCodeElement().getValue();
|
||||
if (isNotBlank(nextSystem) || isNotBlank(nextCode)) {
|
||||
systems.add(nextSystem);
|
||||
codes.add(nextCode);
|
||||
theSystems.add(nextSystem);
|
||||
theCodes.add(nextCode);
|
||||
}
|
||||
|
||||
if (!nextCoding.getDisplayElement().isEmpty()) {
|
||||
systems.add(null);
|
||||
codes.add(nextCoding.getDisplayElement().getValue());
|
||||
addStringParam(theEntity, theListToPopulate, theParameterDef, nextCoding.getDisplayElement().getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -53,17 +53,18 @@ import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
|||
indexes = {
|
||||
@Index(name = "IDX_RES_DATE", columnNames = { "RES_UPDATED" }),
|
||||
@Index(name = "IDX_RES_LANG", columnNames = { "RES_TYPE", "RES_LANGUAGE" }),
|
||||
@Index(name = "IDX_RES_PROFILE", columnNames = { "RES_PROFILE" })
|
||||
@Index(name = "IDX_RES_PROFILE", columnNames = { "RES_PROFILE" }),
|
||||
@Index(name = "IDX_INDEXSTATUS", columnNames = { "SP_INDEX_STATUS" })
|
||||
})
|
||||
//@formatter:on
|
||||
public class ResourceTable extends BaseHasResource implements Serializable {
|
||||
private static final int MAX_LANGUAGE_LENGTH = 20;
|
||||
private static final int MAX_PROFILE_LENGTH = 200;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
static final int RESTYPE_LEN = 30;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Column(name = "SP_HAS_LINKS")
|
||||
private boolean myHasLinks;
|
||||
|
||||
|
@ -74,6 +75,12 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
|||
|
||||
@OneToMany(mappedBy = "myTargetResource", cascade = {}, fetch = FetchType.LAZY, orphanRemoval = false)
|
||||
private Collection<ResourceLink> myIncomingResourceLinks;
|
||||
|
||||
@Column(name = "SP_INDEX_STATUS", nullable=true)
|
||||
private Long myIndexStatus;
|
||||
|
||||
@Column(name = "RES_LANGUAGE", length=MAX_LANGUAGE_LENGTH, nullable=true)
|
||||
private String myLanguage;
|
||||
|
||||
@OneToMany(mappedBy = "myResource", cascade = {}, fetch = FetchType.LAZY, orphanRemoval = false)
|
||||
private Collection<ResourceIndexedSearchParamDate> myParamsDate;
|
||||
|
@ -105,6 +112,9 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
|||
@Column(name = "SP_TOKEN_PRESENT")
|
||||
private boolean myParamsTokenPopulated;
|
||||
|
||||
@Column(name = "RES_PROFILE", length=MAX_PROFILE_LENGTH,nullable=true)
|
||||
private String myProfile;
|
||||
|
||||
@OneToMany(mappedBy = "mySourceResource", cascade = {}, fetch = FetchType.LAZY, orphanRemoval = false)
|
||||
private Collection<ResourceLink> myResourceLinks;
|
||||
|
||||
|
@ -117,34 +127,6 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
|||
@Column(name = "RES_VER")
|
||||
private long myVersion;
|
||||
|
||||
@Column(name = "RES_LANGUAGE", length=MAX_LANGUAGE_LENGTH, nullable=true)
|
||||
private String myLanguage;
|
||||
|
||||
@Column(name = "RES_PROFILE", length=MAX_PROFILE_LENGTH,nullable=true)
|
||||
private String myProfile;
|
||||
|
||||
public String getLanguage() {
|
||||
return myLanguage;
|
||||
}
|
||||
|
||||
public void setLanguage(String theLanguage) {
|
||||
if (defaultString(theLanguage).length()> MAX_LANGUAGE_LENGTH) {
|
||||
throw new UnprocessableEntityException("Language exceeds maximum length of " + MAX_LANGUAGE_LENGTH + " chars: " + theLanguage);
|
||||
}
|
||||
myLanguage = theLanguage;
|
||||
}
|
||||
|
||||
public String getProfile() {
|
||||
return myProfile;
|
||||
}
|
||||
|
||||
public void setProfile(String theProfile) {
|
||||
if (defaultString(theProfile).length()> MAX_PROFILE_LENGTH) {
|
||||
throw new UnprocessableEntityException("Profile name exceeds maximum length of " + MAX_PROFILE_LENGTH + " chars: " + theProfile);
|
||||
}
|
||||
myProfile = theProfile;
|
||||
}
|
||||
|
||||
public ResourceTag addTag(TagDefinition theTag) {
|
||||
ResourceTag tag = new ResourceTag(this, theTag);
|
||||
tag.setResourceType(getResourceType());
|
||||
|
@ -155,12 +137,20 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
|||
public Long getId() {
|
||||
return myId;
|
||||
}
|
||||
|
||||
|
||||
public IdDt getIdDt() {
|
||||
Object id = getForcedId() == null ? myId : getForcedId().getForcedId();
|
||||
return new IdDt(myResourceType + '/' + id + '/' + Constants.PARAM_HISTORY + '/' + myVersion);
|
||||
}
|
||||
|
||||
public Long getIndexStatus() {
|
||||
return myIndexStatus;
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return myLanguage;
|
||||
}
|
||||
|
||||
public Collection<ResourceIndexedSearchParamDate> getParamsDate() {
|
||||
if (myParamsDate == null) {
|
||||
myParamsDate = new ArrayList<ResourceIndexedSearchParamDate>();
|
||||
|
@ -175,7 +165,6 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
|||
return myParamsNumber;
|
||||
}
|
||||
|
||||
|
||||
public Collection<ResourceIndexedSearchParamQuantity> getParamsQuantity() {
|
||||
if(myParamsQuantity==null) {
|
||||
myParamsQuantity=new ArrayList<ResourceIndexedSearchParamQuantity>();
|
||||
|
@ -197,6 +186,11 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
|||
return myParamsToken;
|
||||
}
|
||||
|
||||
public String getProfile() {
|
||||
return myProfile;
|
||||
}
|
||||
|
||||
|
||||
public Collection<ResourceLink> getResourceLinks() {
|
||||
if (myResourceLinks == null) {
|
||||
myResourceLinks = new ArrayList<ResourceLink>();
|
||||
|
@ -260,6 +254,17 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
|||
myId = theId;
|
||||
}
|
||||
|
||||
public void setIndexStatus(Long theIndexStatus) {
|
||||
myIndexStatus = theIndexStatus;
|
||||
}
|
||||
|
||||
public void setLanguage(String theLanguage) {
|
||||
if (defaultString(theLanguage).length()> MAX_LANGUAGE_LENGTH) {
|
||||
throw new UnprocessableEntityException("Language exceeds maximum length of " + MAX_LANGUAGE_LENGTH + " chars: " + theLanguage);
|
||||
}
|
||||
myLanguage = theLanguage;
|
||||
}
|
||||
|
||||
public void setParamsDate(Collection<ResourceIndexedSearchParamDate> theParamsDate) {
|
||||
if (!isParamsDatePopulated() && theParamsDate.isEmpty()) {
|
||||
return;
|
||||
|
@ -320,6 +325,13 @@ public class ResourceTable extends BaseHasResource implements Serializable {
|
|||
myParamsTokenPopulated = theParamsTokenPopulated;
|
||||
}
|
||||
|
||||
public void setProfile(String theProfile) {
|
||||
if (defaultString(theProfile).length()> MAX_PROFILE_LENGTH) {
|
||||
throw new UnprocessableEntityException("Profile name exceeds maximum length of " + MAX_PROFILE_LENGTH + " chars: " + theProfile);
|
||||
}
|
||||
myProfile = theProfile;
|
||||
}
|
||||
|
||||
public void setResourceLinks(List<ResourceLink> theLinks) {
|
||||
if (!isHasLinks() && theLinks.isEmpty()) {
|
||||
return;
|
||||
|
|
|
@ -23,7 +23,7 @@ package ca.uhn.fhir.jpa.provider;
|
|||
import java.util.Collections;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Encounter;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
|
@ -50,8 +50,8 @@ public class BaseJpaResourceProviderEncounterDstu2 extends JpaResourceProviderDs
|
|||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
|
||||
paramMap.setRevIncludes(Collections.singleton(new Include("*")));
|
||||
paramMap.setIncludes(Collections.singleton(new Include("*")));
|
||||
paramMap.setRevIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.add("_id", new StringParam(theId.getIdPart()));
|
||||
ca.uhn.fhir.rest.server.IBundleProvider retVal = getDao().search(paramMap);
|
||||
return retVal;
|
||||
|
|
|
@ -23,7 +23,7 @@ package ca.uhn.fhir.jpa.provider;
|
|||
import java.util.Collections;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
|
@ -48,8 +48,8 @@ public class BaseJpaResourceProviderPatientDstu2 extends JpaResourceProviderDstu
|
|||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
|
||||
paramMap.setRevIncludes(Collections.singleton(new Include("*")));
|
||||
paramMap.setIncludes(Collections.singleton(new Include("*")));
|
||||
paramMap.setRevIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.add("_id", new StringParam(theId.getIdPart()));
|
||||
ca.uhn.fhir.rest.server.IBundleProvider retVal = getDao().search(paramMap);
|
||||
return retVal;
|
||||
|
|
|
@ -23,6 +23,8 @@ package ca.uhn.fhir.jpa.provider;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
|
@ -40,8 +42,6 @@ import ca.uhn.fhir.rest.server.RestfulServer;
|
|||
import ca.uhn.fhir.rest.server.provider.ServerConformanceProvider;
|
||||
import ca.uhn.fhir.util.ExtensionConstants;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public class JpaConformanceProviderDstu1 extends ServerConformanceProvider {
|
||||
|
||||
private String myImplementationDescription;
|
||||
|
|
|
@ -40,6 +40,7 @@ import ca.uhn.fhir.rest.annotation.Operation;
|
|||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||
import ca.uhn.fhir.rest.annotation.Transaction;
|
||||
import ca.uhn.fhir.rest.annotation.TransactionParam;
|
||||
import ca.uhn.fhir.rest.param.NumberParam;
|
||||
|
||||
public class JpaSystemProviderDstu2 extends BaseJpaSystemProvider<Bundle> {
|
||||
|
||||
|
@ -49,7 +50,7 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProvider<Bundle> {
|
|||
|
||||
//@formatter:off
|
||||
// This is generated by hand:
|
||||
// gls hapi-fhir-structures-dstu2/target/generated-sources/tinder/ca/uhn/fhir/model/dstu2/resource/ | sort | sed "s/.java//" | sed "s/^/@OperationParam(name=\"/" | sed "s/$/\", type=IntegerDt.class, min=0, max=1),/"
|
||||
// ls hapi-fhir-structures-dstu2/target/generated-sources/tinder/ca/uhn/fhir/model/dstu2/resource/ | sort | sed "s/.java//" | sed "s/^/@OperationParam(name=\"/" | sed "s/$/\", type=IntegerDt.class, min=0, max=1),/"
|
||||
@Operation(name="$get-resource-counts", idempotent=true, returnParameters= {
|
||||
@OperationParam(name="AllergyIntolerance", type=IntegerDt.class, min=0, max=1),
|
||||
@OperationParam(name="Appointment", type=IntegerDt.class, min=0, max=1),
|
||||
|
@ -157,6 +158,33 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProvider<Bundle> {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
@Operation(name="$mark-all-resources-for-reindexing", idempotent=true, returnParameters= {
|
||||
@OperationParam(name="count", type=IntegerDt.class)
|
||||
})
|
||||
//@formatter:on
|
||||
public Parameters markAllResourcesForReindexing() {
|
||||
int count = mySystemDao.markAllResourcesForReindexing();
|
||||
|
||||
Parameters retVal = new Parameters();
|
||||
retVal.addParameter().setName("count").setValue(new IntegerDt(count));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
@Operation(name="$perform-reindexing-pass", idempotent=true, returnParameters= {
|
||||
@OperationParam(name="count", type=IntegerDt.class)
|
||||
})
|
||||
//@formatter:on
|
||||
public Parameters performReindexingPass(@OperationParam(min=0, max=1, name="count") IntegerDt theCount) {
|
||||
Integer countIn = theCount != null && theCount.getValue()!= null ? theCount.getValue().intValue() : null;
|
||||
int count = mySystemDao.performReindexingPass(countIn);
|
||||
|
||||
Parameters retVal = new Parameters();
|
||||
retVal.addParameter().setName("count").setValue(new IntegerDt(count));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
@Operation(name="$meta", idempotent=true, returnParameters= {
|
||||
@OperationParam(name="return", type=MetaDt.class)
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.transaction.TransactionConfiguration;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.entity.ForcedId;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceHistoryTag;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamDate;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamNumber;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamQuantity;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamToken;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceLink;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceTag;
|
||||
import ca.uhn.fhir.jpa.entity.TagDefinition;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Device;
|
||||
import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Encounter;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Location;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Practitioner;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Questionnaire;
|
||||
import ca.uhn.fhir.model.dstu2.resource.QuestionnaireResponse;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||
|
||||
//@formatter:off
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations={
|
||||
"classpath:hapi-fhir-server-resourceproviders-dstu2.xml",
|
||||
"classpath:fhir-jpabase-spring-test-config.xml"})
|
||||
@TransactionConfiguration(defaultRollback=false)
|
||||
//@formatter:on
|
||||
public class BaseJpaDstu2Test extends BaseJpaTest {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("myDeviceDaoDstu2")
|
||||
protected IFhirResourceDao<Device> myDeviceDao;
|
||||
@Autowired
|
||||
@Qualifier("myDiagnosticReportDaoDstu2")
|
||||
protected IFhirResourceDao<DiagnosticReport> myDiagnosticReportDao;
|
||||
@Autowired
|
||||
@Qualifier("myEncounterDaoDstu2")
|
||||
protected IFhirResourceDao<Encounter> myEncounterDao;
|
||||
@Autowired
|
||||
protected FhirContext myFhirCtx;
|
||||
protected IServerInterceptor myInterceptor;
|
||||
@Autowired
|
||||
@Qualifier("myLocationDaoDstu2")
|
||||
protected IFhirResourceDao<Location> myLocationDao;
|
||||
@Autowired
|
||||
@Qualifier("myObservationDaoDstu2")
|
||||
protected IFhirResourceDao<Observation> myObservationDao;
|
||||
@Autowired
|
||||
@Qualifier("myOrganizationDaoDstu2")
|
||||
protected IFhirResourceDao<Organization> myOrganizationDao;
|
||||
@Autowired
|
||||
@Qualifier("myPatientDaoDstu2")
|
||||
protected IFhirResourceDao<Patient> myPatientDao;
|
||||
@Autowired
|
||||
@Qualifier("myPractitionerDaoDstu2")
|
||||
protected IFhirResourceDao<Practitioner> myPractitionerDao;
|
||||
@Autowired
|
||||
@Qualifier("myQuestionnaireDaoDstu2")
|
||||
protected IFhirResourceDao<Questionnaire> myQuestionnaireDao;
|
||||
@Autowired
|
||||
@Qualifier("myQuestionnaireResponseDaoDstu2")
|
||||
protected IFhirResourceDao<QuestionnaireResponse> myQuestionnaireResponseDao;
|
||||
@Autowired
|
||||
@Qualifier("mySystemDaoDstu2")
|
||||
protected IFhirSystemDao<Bundle> mySystemDao;
|
||||
@Autowired
|
||||
protected DaoConfig myDaoConfig;
|
||||
@Autowired
|
||||
protected PlatformTransactionManager myTxManager;
|
||||
@PersistenceContext()
|
||||
protected EntityManager myEntityManager;
|
||||
|
||||
/**
|
||||
* Just so that JUnit doesn't complain about no test methods in this class
|
||||
*/
|
||||
@Test
|
||||
public void doNothing() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
@Before
|
||||
@Transactional()
|
||||
public void beforePurgeDatabase() {
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(myTxManager);
|
||||
txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRED);
|
||||
txTemplate.execute(new TransactionCallback<Void>() {
|
||||
@Override
|
||||
public Void doInTransaction(TransactionStatus theStatus) {
|
||||
myEntityManager.createQuery("UPDATE " + ResourceHistoryTable.class.getSimpleName() + " d SET d.myForcedId = null").executeUpdate();
|
||||
myEntityManager.createQuery("UPDATE " + ResourceTable.class.getSimpleName() + " d SET d.myForcedId = null").executeUpdate();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
txTemplate.execute(new TransactionCallback<Void>() {
|
||||
@Override
|
||||
public Void doInTransaction(TransactionStatus theStatus) {
|
||||
myEntityManager.createQuery("DELETE from " + ForcedId.class.getSimpleName() + " d").executeUpdate();
|
||||
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamDate.class.getSimpleName() + " d").executeUpdate();
|
||||
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamNumber.class.getSimpleName() + " d").executeUpdate();
|
||||
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamQuantity.class.getSimpleName() + " d").executeUpdate();
|
||||
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamString.class.getSimpleName() + " d").executeUpdate();
|
||||
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamToken.class.getSimpleName() + " d").executeUpdate();
|
||||
myEntityManager.createQuery("DELETE from " + ResourceLink.class.getSimpleName() + " d").executeUpdate();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
txTemplate.execute(new TransactionCallback<Void>() {
|
||||
@Override
|
||||
public Void doInTransaction(TransactionStatus theStatus) {
|
||||
myEntityManager.createQuery("DELETE from " + ResourceHistoryTag.class.getSimpleName() + " d").executeUpdate();
|
||||
myEntityManager.createQuery("DELETE from " + ResourceTag.class.getSimpleName() + " d").executeUpdate();
|
||||
myEntityManager.createQuery("DELETE from " + TagDefinition.class.getSimpleName() + " d").executeUpdate();
|
||||
myEntityManager.createQuery("DELETE from " + ResourceHistoryTable.class.getSimpleName() + " d").executeUpdate();
|
||||
myEntityManager.createQuery("DELETE from " + ResourceTable.class.getSimpleName() + " d").executeUpdate();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Before
|
||||
public void beforeCreateInterceptor() {
|
||||
myInterceptor = mock(IServerInterceptor.class);
|
||||
myDaoConfig.setInterceptors(myInterceptor);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,15 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.AfterClass;
|
||||
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
|
||||
public class BaseJpaTest {
|
||||
|
||||
@AfterClass
|
||||
|
@ -15,4 +21,18 @@ public class BaseJpaTest {
|
|||
// }
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
protected List toList(IBundleProvider theSearch) {
|
||||
return theSearch.getResources(0, theSearch.size());
|
||||
}
|
||||
|
||||
protected List<IIdType> toUnqualifiedVersionlessIds(IBundleProvider theFound) {
|
||||
List<IIdType> retVal = new ArrayList<IIdType>();
|
||||
for (IBaseResource next : theFound.getResources(0, theFound.size())) {
|
||||
retVal.add((IIdType) next.getIdElement().toUnqualifiedVersionless());
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ public class FhirResourceDaoDstu1Test extends BaseJpaTest {
|
|||
ourPatientDao.create(p);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertThat(e.getMessage(), containsString("clients may only assign IDs which begin with a non-numeric"));
|
||||
assertThat(e.getMessage(), containsString("clients may only assign IDs which contain at least one non-numeric"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ public class FhirResourceDaoDstu1Test extends BaseJpaTest {
|
|||
ourPatientDao.update(p1);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertThat(e.getMessage(), containsString("clients may only assign IDs which begin with a non-numeric"));
|
||||
assertThat(e.getMessage(), containsString("clients may only assign IDs which contain at least one non-numeric"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,285 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.endsWith;
|
||||
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.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
||||
|
||||
public class FhirResourceDaoDstu2UpdateTest extends BaseJpaDstu2Test {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2UpdateTest.class);
|
||||
|
||||
@Test
|
||||
public void testUpdateAndGetHistoryResource() throws InterruptedException {
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
patient.addName().addFamily("Tester").addGiven("Joe");
|
||||
|
||||
MethodOutcome outcome = myPatientDao.create(patient);
|
||||
assertNotNull(outcome.getId());
|
||||
assertFalse(outcome.getId().isEmpty());
|
||||
|
||||
assertEquals("1", outcome.getId().getVersionIdPart());
|
||||
|
||||
Date now = new Date();
|
||||
Patient retrieved = myPatientDao.read(outcome.getId());
|
||||
InstantDt published = (InstantDt) retrieved.getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED);
|
||||
InstantDt updated = (InstantDt) retrieved.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED);
|
||||
assertTrue(published.before(now));
|
||||
assertTrue(updated.before(now));
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
reset(myInterceptor);
|
||||
retrieved.getIdentifierFirstRep().setValue("002");
|
||||
MethodOutcome outcome2 = myPatientDao.update(retrieved);
|
||||
assertEquals(outcome.getId().getIdPart(), outcome2.getId().getIdPart());
|
||||
assertNotEquals(outcome.getId().getVersionIdPart(), outcome2.getId().getVersionIdPart());
|
||||
assertEquals("2", outcome2.getId().getVersionIdPart());
|
||||
|
||||
// Verify interceptor
|
||||
ArgumentCaptor<ActionRequestDetails> detailsCapt = ArgumentCaptor.forClass(ActionRequestDetails.class);
|
||||
verify(myInterceptor).incomingRequestPreHandled(eq(RestOperationTypeEnum.UPDATE), detailsCapt.capture());
|
||||
ActionRequestDetails details = detailsCapt.getValue();
|
||||
assertNotNull(details.getId());
|
||||
assertEquals("Patient", details.getResourceType());
|
||||
assertEquals(Patient.class, details.getResource().getClass());
|
||||
|
||||
Date now2 = new Date();
|
||||
|
||||
Patient retrieved2 = myPatientDao.read(outcome.getId().toVersionless());
|
||||
|
||||
assertEquals("2", retrieved2.getId().getVersionIdPart());
|
||||
assertEquals("002", retrieved2.getIdentifierFirstRep().getValue());
|
||||
InstantDt published2 = (InstantDt) retrieved2.getResourceMetadata().get(ResourceMetadataKeyEnum.PUBLISHED);
|
||||
InstantDt updated2 = (InstantDt) retrieved2.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED);
|
||||
assertTrue(published2.before(now));
|
||||
assertTrue(updated2.after(now));
|
||||
assertTrue(updated2.before(now2));
|
||||
|
||||
Thread.sleep(2000);
|
||||
|
||||
/*
|
||||
* Get history
|
||||
*/
|
||||
|
||||
IBundleProvider historyBundle = myPatientDao.history(outcome.getId(), null);
|
||||
|
||||
assertEquals(2, historyBundle.size());
|
||||
|
||||
List<IBaseResource> history = historyBundle.getResources(0, 2);
|
||||
assertEquals("1", history.get(1).getIdElement().getVersionIdPart());
|
||||
assertEquals("2", history.get(0).getIdElement().getVersionIdPart());
|
||||
assertEquals(published, ResourceMetadataKeyEnum.PUBLISHED.get((IResource) history.get(1)));
|
||||
assertEquals(published, ResourceMetadataKeyEnum.PUBLISHED.get((IResource) history.get(1)));
|
||||
assertEquals(updated, ResourceMetadataKeyEnum.UPDATED.get((IResource) history.get(1)));
|
||||
assertEquals("001", ((Patient) history.get(1)).getIdentifierFirstRep().getValue());
|
||||
assertEquals(published2, ResourceMetadataKeyEnum.PUBLISHED.get((IResource) history.get(0)));
|
||||
assertEquals(updated2, ResourceMetadataKeyEnum.UPDATED.get((IResource) history.get(0)));
|
||||
assertEquals("002", ((Patient) history.get(0)).getIdentifierFirstRep().getValue());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateByUrl() {
|
||||
String methodName = "testUpdateByUrl";
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
IIdType id = myPatientDao.create(p).getId();
|
||||
ourLog.info("Created patient, got it: {}", id);
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addFamily("Hello");
|
||||
p.setId("Patient/" + methodName);
|
||||
|
||||
myPatientDao.update(p, "Patient?identifier=urn%3Asystem%7C" + methodName);
|
||||
|
||||
p = myPatientDao.read(id.toVersionless());
|
||||
assertThat(p.getId().toVersionless().toString(), not(containsString("test")));
|
||||
assertEquals(id.toVersionless(), p.getId().toVersionless());
|
||||
assertNotEquals(id, p.getId());
|
||||
assertThat(p.getId().toString(), endsWith("/_history/2"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateCreatesTextualIdIfItDoesntAlreadyExist() {
|
||||
Patient p = new Patient();
|
||||
String methodName = "testUpdateCreatesTextualIdIfItDoesntAlreadyExist";
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addFamily("Hello");
|
||||
p.setId("Patient/" + methodName);
|
||||
|
||||
IIdType id = myPatientDao.update(p).getId();
|
||||
assertEquals("Patient/" + methodName, id.toUnqualifiedVersionless().getValue());
|
||||
|
||||
p = myPatientDao.read(id);
|
||||
assertEquals(methodName, p.getIdentifierFirstRep().getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDoesntFailForUnknownIdWithNumberThenText() {
|
||||
String methodName = "testUpdateFailsForUnknownIdWithNumberThenText";
|
||||
Patient p = new Patient();
|
||||
p.setId("0" + methodName);
|
||||
p.addName().addFamily(methodName);
|
||||
|
||||
myPatientDao.update(p);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMaintainsSearchParams() throws InterruptedException {
|
||||
Patient p1 = new Patient();
|
||||
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateMaintainsSearchParamsDstu2AAA");
|
||||
p1.addName().addFamily("Tester").addGiven("testUpdateMaintainsSearchParamsDstu2AAA");
|
||||
IIdType p1id = myPatientDao.create(p1).getId();
|
||||
|
||||
Patient p2 = new Patient();
|
||||
p2.addIdentifier().setSystem("urn:system").setValue("testUpdateMaintainsSearchParamsDstu2BBB");
|
||||
p2.addName().addFamily("Tester").addGiven("testUpdateMaintainsSearchParamsDstu2BBB");
|
||||
myPatientDao.create(p2).getId();
|
||||
|
||||
Set<Long> ids = myPatientDao.searchForIds(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2AAA"));
|
||||
assertEquals(1, ids.size());
|
||||
assertThat(ids, contains(p1id.getIdPartAsLong()));
|
||||
|
||||
// Update the name
|
||||
p1.getNameFirstRep().getGivenFirstRep().setValue("testUpdateMaintainsSearchParamsDstu2BBB");
|
||||
MethodOutcome update2 = myPatientDao.update(p1);
|
||||
IIdType p1id2 = update2.getId();
|
||||
|
||||
ids = myPatientDao.searchForIds(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2AAA"));
|
||||
assertEquals(0, ids.size());
|
||||
|
||||
ids = myPatientDao.searchForIds(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2BBB"));
|
||||
assertEquals(2, ids.size());
|
||||
|
||||
// Make sure vreads work
|
||||
p1 = myPatientDao.read(p1id);
|
||||
assertEquals("testUpdateMaintainsSearchParamsDstu2AAA", p1.getNameFirstRep().getGivenAsSingleString());
|
||||
|
||||
p1 = myPatientDao.read(p1id2);
|
||||
assertEquals("testUpdateMaintainsSearchParamsDstu2BBB", p1.getNameFirstRep().getGivenAsSingleString());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateRejectsInvalidTypes() throws InterruptedException {
|
||||
Patient p1 = new Patient();
|
||||
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsInvalidTypes");
|
||||
p1.addName().addFamily("Tester").addGiven("testUpdateRejectsInvalidTypes");
|
||||
IIdType p1id = myPatientDao.create(p1).getId();
|
||||
|
||||
Organization p2 = new Organization();
|
||||
p2.getNameElement().setValue("testUpdateRejectsInvalidTypes");
|
||||
try {
|
||||
p2.setId(new IdDt("Organization/" + p1id.getIdPart()));
|
||||
myOrganizationDao.update(p2);
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
// good
|
||||
}
|
||||
|
||||
try {
|
||||
p2.setId(new IdDt("Patient/" + p1id.getIdPart()));
|
||||
myOrganizationDao.update(p2);
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
ourLog.error("Good", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUnknownNumericIdFails() {
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testCreateNumericIdFails");
|
||||
p.addName().addFamily("Hello");
|
||||
p.setId("Patient/9999999999999999");
|
||||
try {
|
||||
myPatientDao.update(p);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertThat(e.getMessage(), containsString("Can not create resource with ID[9999999999999999], no resource with this ID exists and clients may only"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWithInvalidIdFails() {
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testCreateNumericIdFails");
|
||||
p.addName().addFamily("Hello");
|
||||
p.setId("Patient/123:456");
|
||||
try {
|
||||
myPatientDao.update(p);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals("Can not process entity with ID[123:456], this is not a valid FHIR ID", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWithNumericIdFails() {
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testCreateNumericIdFails");
|
||||
p.addName().addFamily("Hello");
|
||||
p.setId("Patient/123");
|
||||
try {
|
||||
myPatientDao.update(p);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertThat(e.getMessage(), containsString("clients may only assign IDs which contain at least one non-numeric"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWithNumericThenTextIdSucceeds() {
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue("testCreateNumericIdFails");
|
||||
p.addName().addFamily("Hello");
|
||||
p.setId("Patient/123abc");
|
||||
IIdType id = myPatientDao.update(p).getId();
|
||||
assertEquals("123abc", id.getIdPart());
|
||||
assertEquals("1", id.getVersionIdPart());
|
||||
|
||||
p = myPatientDao.read(id.toUnqualifiedVersionless());
|
||||
assertEquals("Patient/123abc", p.getId().toUnqualifiedVersionless().getValue());
|
||||
assertEquals("Hello", p.getName().get(0).getFamily().get(0).getValue());
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -14,28 +14,25 @@ import static org.junit.Assert.assertThat;
|
|||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.sql.SQLException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceEncodingEnum;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
||||
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
@ -63,28 +60,82 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
|||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
||||
|
||||
public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
||||
public class FhirSystemDaoDstu2Test extends BaseJpaDstu2Test {
|
||||
|
||||
private static ClassPathXmlApplicationContext ourCtx;
|
||||
private static FhirContext ourFhirContext;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirSystemDaoDstu2Test.class);
|
||||
private static IFhirResourceDao<Observation> ourObservationDao;
|
||||
private static IFhirResourceDao<Patient> ourPatientDao;
|
||||
private static IFhirSystemDao<Bundle> ourSystemDao;
|
||||
private static IServerInterceptor ourInterceptor;
|
||||
|
||||
private void deleteEverything() {
|
||||
FhirSystemDaoDstu2Test.doDeleteEverything(ourSystemDao);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSystemMetaOperation() {
|
||||
deleteEverything();
|
||||
public void testRendexing() {
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily("family");
|
||||
final IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
|
||||
|
||||
ResourceTable entity = new TransactionTemplate(myTxManager).execute(new TransactionCallback<ResourceTable>() {
|
||||
@Override
|
||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
||||
return myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
||||
}});
|
||||
assertEquals(Long.valueOf(1), entity.getIndexStatus());
|
||||
|
||||
mySystemDao.markAllResourcesForReindexing();
|
||||
|
||||
MetaDt meta = ourSystemDao.metaGetOperation();
|
||||
entity = new TransactionTemplate(myTxManager).execute(new TransactionCallback<ResourceTable>() {
|
||||
@Override
|
||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
||||
return myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
||||
}});
|
||||
assertEquals(null, entity.getIndexStatus());
|
||||
|
||||
mySystemDao.performReindexingPass(null);
|
||||
|
||||
entity = new TransactionTemplate(myTxManager).execute(new TransactionCallback<ResourceTable>() {
|
||||
@Override
|
||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
||||
return myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
||||
}});
|
||||
assertEquals(Long.valueOf(1), entity.getIndexStatus());
|
||||
|
||||
// Just make sure this doesn't cause a choke
|
||||
mySystemDao.performReindexingPass(100000);
|
||||
|
||||
// Try making the resource unparseable
|
||||
|
||||
TransactionTemplate template = new TransactionTemplate(myTxManager);
|
||||
template.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
|
||||
template.execute(new TransactionCallback<ResourceTable>() {
|
||||
@Override
|
||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
||||
ResourceTable table = myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
||||
table.setEncoding(ResourceEncodingEnum.JSON);
|
||||
table.setIndexStatus(null);
|
||||
try {
|
||||
table.setResource("{\"resourceType\":\"FOO\"}".getBytes("UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
myEntityManager.merge(table);
|
||||
return null;
|
||||
}});
|
||||
|
||||
mySystemDao.performReindexingPass(null);
|
||||
|
||||
entity = new TransactionTemplate(myTxManager).execute(new TransactionCallback<ResourceTable>() {
|
||||
@Override
|
||||
public ResourceTable doInTransaction(TransactionStatus theStatus) {
|
||||
return myEntityManager.find(ResourceTable.class, id.getIdPartAsLong());
|
||||
}});
|
||||
assertEquals(Long.valueOf(2), entity.getIndexStatus());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSystemMetaOperation() {
|
||||
|
||||
MetaDt meta = mySystemDao.metaGetOperation();
|
||||
List<CodingDt> published = meta.getTag();
|
||||
assertEquals(0, published.size());
|
||||
|
||||
|
@ -106,7 +157,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
profiles.add(new IdDt("http://profile/1"));
|
||||
ResourceMetadataKeyEnum.PROFILES.put(patient, profiles);
|
||||
|
||||
id1 = ourPatientDao.create(patient).getId();
|
||||
id1 = myPatientDao.create(patient).getId();
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
|
@ -124,10 +175,10 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
profiles.add(new IdDt("http://profile/2"));
|
||||
ResourceMetadataKeyEnum.PROFILES.put(patient, profiles);
|
||||
|
||||
ourPatientDao.create(patient);
|
||||
myPatientDao.create(patient);
|
||||
}
|
||||
|
||||
meta = ourSystemDao.metaGetOperation();
|
||||
meta = mySystemDao.metaGetOperation();
|
||||
published = meta.getTag();
|
||||
assertEquals(2, published.size());
|
||||
assertEquals(null, published.get(0).getSystem());
|
||||
|
@ -149,11 +200,11 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
assertEquals("http://profile/1", profiles.get(0).getValue());
|
||||
assertEquals("http://profile/2", profiles.get(1).getValue());
|
||||
|
||||
ourPatientDao.removeTag(id1, TagTypeEnum.TAG, null, "Dog");
|
||||
ourPatientDao.removeTag(id1, TagTypeEnum.SECURITY_LABEL, "seclabel:sys:1", "seclabel:code:1");
|
||||
ourPatientDao.removeTag(id1, TagTypeEnum.PROFILE, BaseHapiFhirDao.NS_JPA_PROFILE, "http://profile/1");
|
||||
myPatientDao.removeTag(id1, TagTypeEnum.TAG, null, "Dog");
|
||||
myPatientDao.removeTag(id1, TagTypeEnum.SECURITY_LABEL, "seclabel:sys:1", "seclabel:code:1");
|
||||
myPatientDao.removeTag(id1, TagTypeEnum.PROFILE, BaseHapiFhirDao.NS_JPA_PROFILE, "http://profile/1");
|
||||
|
||||
meta = ourSystemDao.metaGetOperation();
|
||||
meta = mySystemDao.metaGetOperation();
|
||||
published = meta.getTag();
|
||||
assertEquals(1, published.size());
|
||||
assertEquals("http://foo", published.get(0).getSystem());
|
||||
|
@ -178,7 +229,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.setId("Patient/" + methodName);
|
||||
IIdType id = ourPatientDao.update(p).getId();
|
||||
IIdType id = myPatientDao.update(p).getId();
|
||||
ourLog.info("Created patient, got it: {}", id);
|
||||
|
||||
p = new Patient();
|
||||
|
@ -192,7 +243,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
o.getSubject().setReference("Patient/" + methodName);
|
||||
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
Bundle resp = ourSystemDao.transaction(request);
|
||||
Bundle resp = mySystemDao.transaction(request);
|
||||
assertEquals(2, resp.getEntry().size());
|
||||
|
||||
Entry respEntry = resp.getEntry().get(0);
|
||||
|
@ -206,7 +257,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
assertThat(respEntry.getResponse().getLocation(), endsWith("/_history/1"));
|
||||
assertEquals("1", respEntry.getResponse().getEtag());
|
||||
|
||||
o = (Observation) ourObservationDao.read(new IdDt(respEntry.getResponse().getLocationElement()));
|
||||
o = (Observation) myObservationDao.read(new IdDt(respEntry.getResponse().getLocationElement()));
|
||||
assertEquals(id.toVersionless(), o.getSubject().getReference());
|
||||
assertEquals("1", o.getId().getVersionIdPart());
|
||||
|
||||
|
@ -220,7 +271,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
try {
|
||||
ourSystemDao.transaction(request);
|
||||
mySystemDao.transaction(request);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals("Unable to process transaction where incoming Bundle.type = searchset", e.getMessage());
|
||||
|
@ -240,11 +291,11 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient/THIS_ID_DOESNT_EXIST");
|
||||
|
||||
Bundle resp = ourSystemDao.transaction(request);
|
||||
Bundle resp = mySystemDao.transaction(request);
|
||||
assertEquals(3, resp.getEntry().size());
|
||||
assertEquals(BundleTypeEnum.BATCH_RESPONSE, resp.getTypeElement().getValueAsEnum());
|
||||
|
||||
ourLog.info(ourFhirContext.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||
EntryResponse respEntry;
|
||||
|
||||
// Bundle.entry[0] is operation outcome
|
||||
|
@ -267,7 +318,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
assertEquals("201 Created", respEntry.getStatus());
|
||||
IdDt createdId = new IdDt(respEntry.getLocation());
|
||||
assertEquals("Patient", createdId.getResourceType());
|
||||
ourPatientDao.read(createdId); // shouldn't fail
|
||||
myPatientDao.read(createdId); // shouldn't fail
|
||||
|
||||
// Check GET
|
||||
respEntry = resp.getEntry().get(2).getResponse();
|
||||
|
@ -290,7 +341,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST).setIfNoneExist("Patient?identifier=urn%3Asystem%7C" + methodName);
|
||||
|
||||
try {
|
||||
ourSystemDao.transaction(request);
|
||||
mySystemDao.transaction(request);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals(e.getMessage(),
|
||||
|
@ -312,7 +363,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
try {
|
||||
ourSystemDao.transaction(request);
|
||||
mySystemDao.transaction(request);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals(e.getMessage(),
|
||||
|
@ -326,12 +377,12 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
IIdType id = ourPatientDao.create(p).getId();
|
||||
IIdType id = myPatientDao.create(p).getId();
|
||||
ourLog.info("Created patient, got it: {}", id);
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
id = ourPatientDao.create(p).getId();
|
||||
id = myPatientDao.create(p).getId();
|
||||
ourLog.info("Created patient, got it: {}", id);
|
||||
|
||||
Bundle request = new Bundle();
|
||||
|
@ -347,7 +398,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
try {
|
||||
ourSystemDao.transaction(request);
|
||||
mySystemDao.transaction(request);
|
||||
fail();
|
||||
} catch (PreconditionFailedException e) {
|
||||
assertThat(e.getMessage(), containsString("with match URL \"Patient"));
|
||||
|
@ -370,7 +421,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
o.getSubject().setReference("Patient/" + methodName);
|
||||
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
Bundle resp = ourSystemDao.transaction(request);
|
||||
Bundle resp = mySystemDao.transaction(request);
|
||||
assertEquals(BundleTypeEnum.TRANSACTION_RESPONSE, resp.getTypeElement().getValueAsEnum());
|
||||
assertEquals(2, resp.getEntry().size());
|
||||
|
||||
|
@ -388,7 +439,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
assertThat(respEntry.getResponse().getLocation(), endsWith("/_history/1"));
|
||||
assertEquals("1", respEntry.getResponse().getEtag());
|
||||
|
||||
o = (Observation) ourObservationDao.read(new IdDt(respEntry.getResponse().getLocationElement()));
|
||||
o = (Observation) myObservationDao.read(new IdDt(respEntry.getResponse().getLocationElement()));
|
||||
assertEquals(new IdDt(patientId).toUnqualifiedVersionless(), o.getSubject().getReference());
|
||||
}
|
||||
|
||||
|
@ -402,7 +453,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
p.setId("Patient/" + methodName);
|
||||
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST).setIfNoneExist("Patient?identifier=urn%3Asystem%7C" + methodName);
|
||||
|
||||
Bundle resp = ourSystemDao.transaction(request);
|
||||
Bundle resp = mySystemDao.transaction(request);
|
||||
assertEquals(1, resp.getEntry().size());
|
||||
|
||||
Entry respEntry = resp.getEntry().get(0);
|
||||
|
@ -415,13 +466,13 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
* embedded operation
|
||||
*/
|
||||
ArgumentCaptor<ActionRequestDetails> detailsCapt = ArgumentCaptor.forClass(ActionRequestDetails.class);
|
||||
verify(ourInterceptor).incomingRequestPreHandled(eq(RestOperationTypeEnum.TRANSACTION), detailsCapt.capture());
|
||||
verify(myInterceptor).incomingRequestPreHandled(eq(RestOperationTypeEnum.TRANSACTION), detailsCapt.capture());
|
||||
ActionRequestDetails details = detailsCapt.getValue();
|
||||
assertEquals("Bundle", details.getResourceType());
|
||||
assertEquals(Bundle.class, details.getResource().getClass());
|
||||
|
||||
detailsCapt = ArgumentCaptor.forClass(ActionRequestDetails.class);
|
||||
verify(ourInterceptor).incomingRequestPreHandled(eq(RestOperationTypeEnum.CREATE), detailsCapt.capture());
|
||||
verify(myInterceptor).incomingRequestPreHandled(eq(RestOperationTypeEnum.CREATE), detailsCapt.capture());
|
||||
details = detailsCapt.getValue();
|
||||
assertNotNull(details.getId());
|
||||
assertEquals("Patient", details.getResourceType());
|
||||
|
@ -441,7 +492,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
try {
|
||||
ourSystemDao.transaction(request);
|
||||
mySystemDao.transaction(request);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertThat(e.getMessage(), containsString("Resource Organization/9999999999999999 not found, specified in path: Patient.managingOrganization"));
|
||||
|
@ -460,7 +511,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
request.addEntry().setResource(p).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
try {
|
||||
ourSystemDao.transaction(request);
|
||||
mySystemDao.transaction(request);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertThat(e.getMessage(), containsString("Resource Organization/" + methodName + " not found, specified in path: Patient.managingOrganization"));
|
||||
|
@ -473,13 +524,13 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
Patient p1 = new Patient();
|
||||
p1.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
IIdType id1 = ourPatientDao.create(p1).getId();
|
||||
IIdType id1 = myPatientDao.create(p1).getId();
|
||||
ourLog.info("Created patient, got it: {}", id1);
|
||||
|
||||
Patient p2 = new Patient();
|
||||
p2.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p2.setId("Patient/" + methodName);
|
||||
IIdType id2 = ourPatientDao.update(p2).getId();
|
||||
IIdType id2 = myPatientDao.update(p2).getId();
|
||||
ourLog.info("Created patient, got it: {}", id2);
|
||||
|
||||
Bundle request = new Bundle();
|
||||
|
@ -487,24 +538,24 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.DELETE).setUrl("Patient/" + id1.getIdPart());
|
||||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.DELETE).setUrl("Patient/" + id2.getIdPart());
|
||||
|
||||
ourPatientDao.read(id1.toVersionless());
|
||||
ourPatientDao.read(id2.toVersionless());
|
||||
myPatientDao.read(id1.toVersionless());
|
||||
myPatientDao.read(id2.toVersionless());
|
||||
|
||||
Bundle resp = ourSystemDao.transaction(request);
|
||||
Bundle resp = mySystemDao.transaction(request);
|
||||
|
||||
assertEquals(2, resp.getEntry().size());
|
||||
assertEquals("204 No Content", resp.getEntry().get(0).getResponse().getStatus());
|
||||
assertEquals("204 No Content", resp.getEntry().get(1).getResponse().getStatus());
|
||||
|
||||
try {
|
||||
ourPatientDao.read(id1.toVersionless());
|
||||
myPatientDao.read(id1.toVersionless());
|
||||
fail();
|
||||
} catch (ResourceGoneException e) {
|
||||
// good
|
||||
}
|
||||
|
||||
try {
|
||||
ourPatientDao.read(id2.toVersionless());
|
||||
myPatientDao.read(id2.toVersionless());
|
||||
fail();
|
||||
} catch (ResourceGoneException e) {
|
||||
// good
|
||||
|
@ -518,33 +569,33 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
IIdType id = ourPatientDao.create(p).getId();
|
||||
IIdType id = myPatientDao.create(p).getId();
|
||||
ourLog.info("Created patient, got it: {}", id);
|
||||
|
||||
Bundle request = new Bundle();
|
||||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.DELETE).setUrl("Patient?identifier=urn%3Asystem%7C" + methodName);
|
||||
|
||||
Bundle resp = ourSystemDao.transaction(request);
|
||||
Bundle resp = mySystemDao.transaction(request);
|
||||
assertEquals(1, resp.getEntry().size());
|
||||
|
||||
Entry nextEntry = resp.getEntry().get(0);
|
||||
assertEquals(Constants.STATUS_HTTP_204_NO_CONTENT + " No Content", nextEntry.getResponse().getStatus());
|
||||
|
||||
try {
|
||||
ourPatientDao.read(id.toVersionless());
|
||||
myPatientDao.read(id.toVersionless());
|
||||
fail();
|
||||
} catch (ResourceGoneException e) {
|
||||
// ok
|
||||
}
|
||||
|
||||
try {
|
||||
ourPatientDao.read(new IdDt("Patient/" + methodName));
|
||||
myPatientDao.read(new IdDt("Patient/" + methodName));
|
||||
fail();
|
||||
} catch (ResourceNotFoundException e) {
|
||||
// ok
|
||||
}
|
||||
|
||||
IBundleProvider history = ourPatientDao.history(id, null);
|
||||
IBundleProvider history = myPatientDao.history(id, null);
|
||||
assertEquals(2, history.size());
|
||||
|
||||
assertNotNull(ResourceMetadataKeyEnum.DELETED_AT.get((IResource) history.getResources(0, 0).get(0)));
|
||||
|
@ -559,12 +610,12 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
IIdType id = ourPatientDao.create(p).getId();
|
||||
IIdType id = myPatientDao.create(p).getId();
|
||||
ourLog.info("Created patient, got it: {}", id);
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
id = ourPatientDao.create(p).getId();
|
||||
id = myPatientDao.create(p).getId();
|
||||
ourLog.info("Created patient, got it: {}", id);
|
||||
|
||||
p = new Patient();
|
||||
|
@ -576,7 +627,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.DELETE).setUrl("Patient?identifier=urn%3Asystem%7C" + methodName);
|
||||
|
||||
try {
|
||||
ourSystemDao.transaction(request);
|
||||
mySystemDao.transaction(request);
|
||||
fail();
|
||||
} catch (ResourceNotFoundException e) {
|
||||
assertThat(e.getMessage(), containsString("resource with match URL \"Patient?"));
|
||||
|
@ -591,7 +642,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.DELETE).setUrl("Patient?identifier=urn%3Asystem%7C" + methodName);
|
||||
|
||||
try {
|
||||
ourSystemDao.transaction(request);
|
||||
mySystemDao.transaction(request);
|
||||
fail();
|
||||
} catch (ResourceNotFoundException e) {
|
||||
assertThat(e.getMessage(), containsString("resource matching URL \"Patient?"));
|
||||
|
@ -605,19 +656,19 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.setId("Patient/" + methodName);
|
||||
IIdType id = ourPatientDao.update(p).getId();
|
||||
IIdType id = myPatientDao.update(p).getId();
|
||||
ourLog.info("Created patient, got it: {}", id);
|
||||
|
||||
Bundle request = new Bundle();
|
||||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.DELETE).setUrl("Patient?identifier=urn%3Asystem%7C" + methodName);
|
||||
|
||||
Bundle res = ourSystemDao.transaction(request);
|
||||
Bundle res = mySystemDao.transaction(request);
|
||||
assertEquals(1, res.getEntry().size());
|
||||
|
||||
assertEquals(Constants.STATUS_HTTP_204_NO_CONTENT + " No Content", res.getEntry().get(0).getResponse().getStatus());
|
||||
|
||||
try {
|
||||
ourPatientDao.read(id.toVersionless());
|
||||
myPatientDao.read(id.toVersionless());
|
||||
fail();
|
||||
} catch (ResourceGoneException e) {
|
||||
// ok
|
||||
|
@ -638,7 +689,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
patient2.addIdentifier().setSystem("urn:system").setValue("testPersistWithSimpleLinkP02");
|
||||
request.addEntry().setResource(patient2).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
ourSystemDao.transaction(request);
|
||||
mySystemDao.transaction(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -646,17 +697,17 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/transaction_link_patient_eve.xml");
|
||||
String bundleStr = IOUtils.toString(bundleRes);
|
||||
Bundle bundle = ourFhirContext.newXmlParser().parseResource(Bundle.class, bundleStr);
|
||||
Bundle bundle = myFhirCtx.newXmlParser().parseResource(Bundle.class, bundleStr);
|
||||
|
||||
Bundle resp = ourSystemDao.transaction(bundle);
|
||||
Bundle resp = mySystemDao.transaction(bundle);
|
||||
|
||||
ourLog.info(ourFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||
|
||||
assertThat(resp.getEntry().get(0).getResponse().getLocation(), startsWith("Patient/a555-44-4444/_history/"));
|
||||
assertThat(resp.getEntry().get(1).getResponse().getLocation(), startsWith("Patient/temp6789/_history/"));
|
||||
assertThat(resp.getEntry().get(2).getResponse().getLocation(), startsWith("Organization/GHH/_history/"));
|
||||
|
||||
Patient p = ourPatientDao.read(new IdDt("Patient/a555-44-4444/_history/1"));
|
||||
Patient p = myPatientDao.read(new IdDt("Patient/a555-44-4444/_history/1"));
|
||||
assertEquals("Patient/temp6789", p.getLink().get(0).getOther().getReference().getValue());
|
||||
}
|
||||
|
||||
|
@ -665,11 +716,11 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/josh-bundle.json");
|
||||
String bundleStr = IOUtils.toString(bundleRes);
|
||||
Bundle bundle = ourFhirContext.newJsonParser().parseResource(Bundle.class, bundleStr);
|
||||
Bundle bundle = myFhirCtx.newJsonParser().parseResource(Bundle.class, bundleStr);
|
||||
|
||||
Bundle resp = ourSystemDao.transaction(bundle);
|
||||
Bundle resp = mySystemDao.transaction(bundle);
|
||||
|
||||
ourLog.info(ourFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||
|
||||
assertEquals("201 Created", resp.getEntry().get(0).getResponse().getStatus());
|
||||
assertEquals("201 Created", resp.getEntry().get(1).getResponse().getStatus());
|
||||
|
@ -682,14 +733,14 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.setId("Patient/" + methodName);
|
||||
IIdType idv1 = ourPatientDao.update(p).getId();
|
||||
IIdType idv1 = myPatientDao.update(p).getId();
|
||||
ourLog.info("Created patient, got id: {}", idv1);
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addFamily("Family Name");
|
||||
p.setId("Patient/" + methodName);
|
||||
IIdType idv2 = ourPatientDao.update(p).getId();
|
||||
IIdType idv2 = myPatientDao.update(p).getId();
|
||||
ourLog.info("Updated patient, got id: {}", idv2);
|
||||
|
||||
Bundle request = new Bundle();
|
||||
|
@ -697,7 +748,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl(idv1.toUnqualified().getValue());
|
||||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient?identifier=urn%3Asystem%7C" + methodName);
|
||||
|
||||
Bundle resp = ourSystemDao.transaction(request);
|
||||
Bundle resp = mySystemDao.transaction(request);
|
||||
|
||||
assertEquals(3, resp.getEntry().size());
|
||||
|
||||
|
@ -721,25 +772,25 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
* embedded operation
|
||||
*/
|
||||
ArgumentCaptor<ActionRequestDetails> detailsCapt = ArgumentCaptor.forClass(ActionRequestDetails.class);
|
||||
verify(ourInterceptor, times(1)).incomingRequestPreHandled(eq(RestOperationTypeEnum.TRANSACTION), detailsCapt.capture());
|
||||
verify(myInterceptor, times(1)).incomingRequestPreHandled(eq(RestOperationTypeEnum.TRANSACTION), detailsCapt.capture());
|
||||
ActionRequestDetails details = detailsCapt.getValue();
|
||||
assertEquals("Bundle", details.getResourceType());
|
||||
assertEquals(Bundle.class, details.getResource().getClass());
|
||||
|
||||
detailsCapt = ArgumentCaptor.forClass(ActionRequestDetails.class);
|
||||
verify(ourInterceptor, times(1)).incomingRequestPreHandled(eq(RestOperationTypeEnum.READ), detailsCapt.capture());
|
||||
verify(myInterceptor, times(1)).incomingRequestPreHandled(eq(RestOperationTypeEnum.READ), detailsCapt.capture());
|
||||
details = detailsCapt.getValue();
|
||||
assertEquals(idv1.toUnqualifiedVersionless(), details.getId());
|
||||
assertEquals("Patient", details.getResourceType());
|
||||
|
||||
detailsCapt = ArgumentCaptor.forClass(ActionRequestDetails.class);
|
||||
verify(ourInterceptor, times(1)).incomingRequestPreHandled(eq(RestOperationTypeEnum.VREAD), detailsCapt.capture());
|
||||
verify(myInterceptor, times(1)).incomingRequestPreHandled(eq(RestOperationTypeEnum.VREAD), detailsCapt.capture());
|
||||
details = detailsCapt.getValue();
|
||||
assertEquals(idv1.toUnqualified(), details.getId());
|
||||
assertEquals("Patient", details.getResourceType());
|
||||
|
||||
detailsCapt = ArgumentCaptor.forClass(ActionRequestDetails.class);
|
||||
verify(ourInterceptor, times(1)).incomingRequestPreHandled(eq(RestOperationTypeEnum.SEARCH_TYPE), detailsCapt.capture());
|
||||
verify(myInterceptor, times(1)).incomingRequestPreHandled(eq(RestOperationTypeEnum.SEARCH_TYPE), detailsCapt.capture());
|
||||
details = detailsCapt.getValue();
|
||||
assertEquals("Patient", details.getResourceType());
|
||||
|
||||
|
@ -753,19 +804,19 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.setId("Patient/" + methodName);
|
||||
IIdType idv1 = ourPatientDao.update(p).getId();
|
||||
IIdType idv1 = myPatientDao.update(p).getId();
|
||||
ourLog.info("Created patient, got id: {}", idv1);
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addFamily("Family Name");
|
||||
p.setId("Patient/" + methodName);
|
||||
IIdType idv2 = ourPatientDao.update(p).getId();
|
||||
IIdType idv2 = myPatientDao.update(p).getId();
|
||||
ourLog.info("Updated patient, got id: {}", idv2);
|
||||
|
||||
Bundle request = new Bundle();
|
||||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient?" + Constants.PARAM_COUNT + "=1");
|
||||
Bundle resp = ourSystemDao.transaction(request);
|
||||
Bundle resp = mySystemDao.transaction(request);
|
||||
|
||||
assertEquals(1, resp.getEntry().size());
|
||||
|
||||
|
@ -779,7 +830,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
request = new Bundle();
|
||||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient?" + Constants.PARAM_COUNT + "=GKJGKJG");
|
||||
try {
|
||||
ourSystemDao.transaction(request);
|
||||
mySystemDao.transaction(request);
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals(e.getMessage(), ("Invalid _count value: GKJGKJG"));
|
||||
}
|
||||
|
@ -788,7 +839,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
request = new Bundle();
|
||||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl("Patient?" + Constants.PARAM_COUNT + "=");
|
||||
respBundle = ourSystemDao.transaction(request);
|
||||
respBundle = mySystemDao.transaction(request);
|
||||
assertThat(respBundle.getEntry().size(), greaterThan(0));
|
||||
}
|
||||
|
||||
|
@ -799,14 +850,14 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.setId("Patient/" + methodName);
|
||||
IIdType idv1 = ourPatientDao.update(p).getId();
|
||||
IIdType idv1 = myPatientDao.update(p).getId();
|
||||
ourLog.info("Created patient, got id: {}", idv1);
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addFamily("Family Name");
|
||||
p.setId("Patient/" + methodName);
|
||||
IIdType idv2 = ourPatientDao.update(p).getId();
|
||||
IIdType idv2 = myPatientDao.update(p).getId();
|
||||
ourLog.info("Updated patient, got id: {}", idv2);
|
||||
|
||||
Bundle request = new Bundle();
|
||||
|
@ -814,7 +865,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl(idv1.toUnqualifiedVersionless().getValue()).setIfNoneMatch("W/\"" + idv1.getVersionIdPart() + "\"");
|
||||
request.addEntry().getRequest().setMethod(HTTPVerbEnum.GET).setUrl(idv1.toUnqualifiedVersionless().getValue()).setIfNoneMatch("W/\"" + idv2.getVersionIdPart() + "\"");
|
||||
|
||||
Bundle resp = ourSystemDao.transaction(request);
|
||||
Bundle resp = mySystemDao.transaction(request);
|
||||
|
||||
assertEquals(3, resp.getEntry().size());
|
||||
|
||||
|
@ -844,7 +895,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
IIdType id = ourPatientDao.create(p).getId();
|
||||
IIdType id = myPatientDao.create(p).getId();
|
||||
ourLog.info("Created patient, got it: {}", id);
|
||||
|
||||
p = new Patient();
|
||||
|
@ -858,7 +909,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
o.getSubject().setReference("Patient/" + methodName);
|
||||
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
Bundle resp = ourSystemDao.transaction(request);
|
||||
Bundle resp = mySystemDao.transaction(request);
|
||||
assertEquals(2, resp.getEntry().size());
|
||||
|
||||
Entry nextEntry = resp.getEntry().get(0);
|
||||
|
@ -873,7 +924,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
assertThat(nextEntry.getResponse().getLocation(), not(emptyString()));
|
||||
|
||||
nextEntry = resp.getEntry().get(1);
|
||||
o = ourObservationDao.read(new IdDt(nextEntry.getResponse().getLocation()));
|
||||
o = myObservationDao.read(new IdDt(nextEntry.getResponse().getLocation()));
|
||||
assertEquals(id.toVersionless(), o.getSubject().getReference());
|
||||
|
||||
}
|
||||
|
@ -885,12 +936,12 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
IIdType id = ourPatientDao.create(p).getId();
|
||||
IIdType id = myPatientDao.create(p).getId();
|
||||
ourLog.info("Created patient, got it: {}", id);
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
id = ourPatientDao.create(p).getId();
|
||||
id = myPatientDao.create(p).getId();
|
||||
ourLog.info("Created patient, got it: {}", id);
|
||||
|
||||
p = new Patient();
|
||||
|
@ -905,7 +956,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
try {
|
||||
ourSystemDao.transaction(request);
|
||||
mySystemDao.transaction(request);
|
||||
fail();
|
||||
} catch (PreconditionFailedException e) {
|
||||
assertThat(e.getMessage(), containsString("with match URL \"Patient"));
|
||||
|
@ -919,7 +970,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily("Hello");
|
||||
IIdType id = ourPatientDao.create(p).getId();
|
||||
IIdType id = myPatientDao.create(p).getId();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
|
@ -932,7 +983,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
o.getSubject().setReference("Patient/" + methodName);
|
||||
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
Bundle resp = ourSystemDao.transaction(request);
|
||||
Bundle resp = mySystemDao.transaction(request);
|
||||
assertEquals(2, resp.getEntry().size());
|
||||
|
||||
Entry nextEntry = resp.getEntry().get(0);
|
||||
|
@ -945,7 +996,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
assertThat(patientId.getValue(), endsWith("/_history/1"));
|
||||
|
||||
nextEntry = resp.getEntry().get(1);
|
||||
o = ourObservationDao.read(new IdDt(nextEntry.getResponse().getLocation()));
|
||||
o = myObservationDao.read(new IdDt(nextEntry.getResponse().getLocation()));
|
||||
assertEquals(patientId.toVersionless(), o.getSubject().getReference());
|
||||
|
||||
}
|
||||
|
@ -958,7 +1009,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.setId("Patient/" + methodName);
|
||||
IIdType id = ourPatientDao.update(p).getId();
|
||||
IIdType id = myPatientDao.update(p).getId();
|
||||
ourLog.info("Created patient, got it: {}", id);
|
||||
|
||||
p = new Patient();
|
||||
|
@ -972,7 +1023,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
o.getSubject().setReference("Patient/" + methodName);
|
||||
request.addEntry().setResource(o).getRequest().setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
Bundle resp = ourSystemDao.transaction(request);
|
||||
Bundle resp = mySystemDao.transaction(request);
|
||||
assertEquals(2, resp.getEntry().size());
|
||||
|
||||
Entry nextEntry = resp.getEntry().get(0);
|
||||
|
@ -986,7 +1037,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
nextEntry = resp.getEntry().get(1);
|
||||
assertEquals(Constants.STATUS_HTTP_201_CREATED + " Created", nextEntry.getResponse().getStatus());
|
||||
|
||||
o = ourObservationDao.read(new IdDt(resp.getEntry().get(1).getResponse().getLocation()));
|
||||
o = myObservationDao.read(new IdDt(resp.getEntry().get(1).getResponse().getLocation()));
|
||||
assertEquals(id.toVersionless(), o.getSubject().getReference());
|
||||
|
||||
}
|
||||
|
@ -1115,9 +1166,9 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
o2.setSubject(new ResourceReferenceDt("urn:oid:0.1.2.3"));
|
||||
res.addEntry().setResource(o2).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Observation");
|
||||
|
||||
Bundle resp = ourSystemDao.transaction(res);
|
||||
Bundle resp = mySystemDao.transaction(res);
|
||||
|
||||
ourLog.info(ourFhirContext.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||
|
||||
assertEquals(BundleTypeEnum.TRANSACTION_RESPONSE, resp.getTypeElement().getValueAsEnum());
|
||||
assertEquals(3, resp.getEntry().size());
|
||||
|
@ -1126,8 +1177,8 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
assertTrue(resp.getEntry().get(1).getResponse().getLocation(), new IdDt(resp.getEntry().get(1).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
|
||||
assertTrue(resp.getEntry().get(2).getResponse().getLocation(), new IdDt(resp.getEntry().get(2).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
|
||||
|
||||
o1 = ourObservationDao.read(new IdDt(resp.getEntry().get(1).getResponse().getLocation()));
|
||||
o2 = ourObservationDao.read(new IdDt(resp.getEntry().get(2).getResponse().getLocation()));
|
||||
o1 = myObservationDao.read(new IdDt(resp.getEntry().get(1).getResponse().getLocation()));
|
||||
o2 = myObservationDao.read(new IdDt(resp.getEntry().get(2).getResponse().getLocation()));
|
||||
assertThat(o1.getSubject().getReference().getValue(), endsWith("Patient/" + p1.getId().getIdPart()));
|
||||
assertThat(o2.getSubject().getReference().getValue(), endsWith("Patient/" + p1.getId().getIdPart()));
|
||||
|
||||
|
@ -1158,9 +1209,9 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
o2.setSubject(new ResourceReferenceDt("Patient/urn:oid:0.1.2.3"));
|
||||
res.addEntry().setResource(o2).getRequest().setMethod(HTTPVerbEnum.POST).setUrl("Observation");
|
||||
|
||||
Bundle resp = ourSystemDao.transaction(res);
|
||||
Bundle resp = mySystemDao.transaction(res);
|
||||
|
||||
ourLog.info(ourFhirContext.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||
|
||||
assertEquals(BundleTypeEnum.TRANSACTION_RESPONSE, resp.getTypeElement().getValueAsEnum());
|
||||
assertEquals(3, resp.getEntry().size());
|
||||
|
@ -1169,38 +1220,13 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
|
|||
assertTrue(resp.getEntry().get(1).getResponse().getLocation(), new IdDt(resp.getEntry().get(1).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
|
||||
assertTrue(resp.getEntry().get(2).getResponse().getLocation(), new IdDt(resp.getEntry().get(2).getResponse().getLocation()).getIdPart().matches("^[0-9]+$"));
|
||||
|
||||
o1 = ourObservationDao.read(new IdDt(resp.getEntry().get(1).getResponse().getLocation()));
|
||||
o2 = ourObservationDao.read(new IdDt(resp.getEntry().get(2).getResponse().getLocation()));
|
||||
o1 = myObservationDao.read(new IdDt(resp.getEntry().get(1).getResponse().getLocation()));
|
||||
o2 = myObservationDao.read(new IdDt(resp.getEntry().get(2).getResponse().getLocation()));
|
||||
assertThat(o1.getSubject().getReference().getValue(), endsWith("Patient/" + p1.getId().getIdPart()));
|
||||
assertThat(o2.getSubject().getReference().getValue(), endsWith("Patient/" + p1.getId().getIdPart()));
|
||||
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws SQLException {
|
||||
ourCtx.close();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
ourCtx = new ClassPathXmlApplicationContext("hapi-fhir-server-resourceproviders-dstu2.xml", "fhir-jpabase-spring-test-config.xml");
|
||||
ourFhirContext = ourCtx.getBean(FhirContext.class);
|
||||
assertEquals(FhirVersionEnum.DSTU2, ourFhirContext.getVersion().getVersion());
|
||||
ourPatientDao = ourCtx.getBean("myPatientDaoDstu2", IFhirResourceDao.class);
|
||||
ourObservationDao = ourCtx.getBean("myObservationDaoDstu2", IFhirResourceDao.class);
|
||||
ourSystemDao = ourCtx.getBean("mySystemDaoDstu2", IFhirSystemDao.class);
|
||||
ourInterceptor = mock(IServerInterceptor.class);
|
||||
|
||||
DaoConfig daoConfig = ourCtx.getBean(DaoConfig.class);
|
||||
daoConfig.setInterceptors(ourInterceptor);
|
||||
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
reset(ourInterceptor);
|
||||
}
|
||||
|
||||
static void doDeleteEverything(IFhirSystemDao<Bundle> systemDao) {
|
||||
IBundleProvider all = systemDao.history(null);
|
||||
|
|
|
@ -6,8 +6,14 @@ import static org.junit.Assert.*;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
|
@ -21,6 +27,7 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.jpa.dao.BaseJpaTest;
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
||||
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
@ -63,6 +70,8 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
|||
// private static IFhirResourceDao<Patient> ourPatientDao;
|
||||
// private static IFhirResourceDao<Questionnaire> ourQuestionnaireDao;
|
||||
private static Server ourServer;
|
||||
private static String ourServerBase;
|
||||
private static CloseableHttpClient ourHttpClient;
|
||||
|
||||
// private static JpaConformanceProvider ourConfProvider;
|
||||
|
||||
|
@ -165,7 +174,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
|||
.forResource(Encounter.class)
|
||||
.where(Encounter.IDENTIFIER.exactly().systemAndCode("urn:foo", "testDeepChainingE1"))
|
||||
.include(Encounter.INCLUDE_LOCATION_LOCATION)
|
||||
.include(Location.INCLUDE_PARTOF)
|
||||
.include(Location.INCLUDE_PARTOF.asRecursive())
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
|
@ -482,6 +491,22 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
|||
assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getId().getIdPart());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetadata() throws Exception {
|
||||
HttpGet get = new HttpGet(ourServerBase + "/metadata");
|
||||
CloseableHttpResponse response = ourHttpClient.execute(get);
|
||||
try {
|
||||
String resp = IOUtils.toString(response.getEntity().getContent());
|
||||
ourLog.info(resp);
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
assertThat(resp, stringContainsInOrder("THIS IS THE DESC"));
|
||||
} finally {
|
||||
IOUtils.closeQuietly(response.getEntity().getContent());
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
|
@ -496,7 +521,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
|||
|
||||
RestfulServer restServer = new RestfulServer(ourCtx);
|
||||
|
||||
String serverBase = "http://localhost:" + port + "/fhir/context";
|
||||
ourServerBase = "http://localhost:" + port + "/fhir/context";
|
||||
|
||||
ourAppCtx = new ClassPathXmlApplicationContext("hapi-fhir-server-resourceproviders-dstu1.xml", "fhir-jpabase-spring-test-config.xml");
|
||||
|
||||
|
@ -514,6 +539,11 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
|||
|
||||
restServer.setPagingProvider(new FifoMemoryPagingProvider(10));
|
||||
|
||||
IFhirSystemDao<List<IResource>> systemDao = ourAppCtx.getBean(IFhirSystemDao.class);
|
||||
JpaConformanceProviderDstu1 confProvider = new JpaConformanceProviderDstu1(restServer, systemDao);
|
||||
confProvider.setImplementationDescription("THIS IS THE DESC");
|
||||
restServer.setServerConformanceProvider(confProvider);
|
||||
|
||||
ourServer = new Server(port);
|
||||
|
||||
ServletContextHandler proxyHandler = new ServletContextHandler();
|
||||
|
@ -526,9 +556,14 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
|
|||
ourServer.setHandler(proxyHandler);
|
||||
ourServer.start();
|
||||
|
||||
ourClient = ourCtx.newRestfulGenericClient(serverBase);
|
||||
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
|
||||
ourClient.registerInterceptor(new LoggingInterceptor(true));
|
||||
|
||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||
builder.setConnectionManager(connectionManager);
|
||||
ourHttpClient = builder.build();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpDelete;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
|
@ -57,6 +58,7 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.jpa.dao.BaseJpaTest;
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
||||
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.BundleEntry;
|
||||
|
@ -122,14 +124,18 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderDstu2Test.class);
|
||||
private static IFhirResourceDao<Organization> ourOrganizationDao;
|
||||
private static int ourPort;
|
||||
// private static IFhirResourceDao<Observation> ourObservationDao;
|
||||
// private static IFhirResourceDao<Patient> ourPatientDao;
|
||||
// private static IFhirResourceDao<Questionnaire> ourQuestionnaireDao;
|
||||
private static Server ourServer;
|
||||
private static String ourServerBase;
|
||||
|
||||
// private static JpaConformanceProvider ourConfProvider;
|
||||
|
||||
private void checkParamMissing(String paramName) throws IOException, ClientProtocolException {
|
||||
HttpGet get = new HttpGet(ourServerBase + "/Observation?" + paramName + ":missing=false");
|
||||
CloseableHttpResponse resp = ourHttpClient.execute(get);
|
||||
IOUtils.closeQuietly(resp.getEntity().getContent());
|
||||
assertEquals(200, resp.getStatusLine().getStatusCode());
|
||||
}
|
||||
|
||||
private void delete(String theResourceType, String theParamName, String theParamValue) {
|
||||
Bundle resources;
|
||||
do {
|
||||
|
@ -145,148 +151,6 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
} while (resources.size() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* See #198
|
||||
*/
|
||||
@Test
|
||||
public void testSortFromResourceProvider() {
|
||||
Patient p;
|
||||
String methodName = "testSortFromResourceProvider";
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Daniel").addFamily("Adams");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Aaron").addFamily("Alexis");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Carol").addFamily("Allen");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Ruth").addFamily("Black");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Brian").addFamily("Brooks");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Susan").addFamily("Clark");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Amy").addFamily("Clark");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Anthony").addFamily("Coleman");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Steven").addFamily("Coleman");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Lisa").addFamily("Coleman");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Ruth").addFamily("Cook");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Betty").addFamily("Davis");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Joshua").addFamily("Diaz");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Brian").addFamily("Gracia");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Stephan").addFamily("Graham");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Sarah").addFamily("Graham");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
//@formatter:off
|
||||
Bundle resp = ourClient
|
||||
.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.IDENTIFIER.exactly().systemAndCode("urn:system", methodName))
|
||||
.sort().ascending(Patient.FAMILY)
|
||||
.sort().ascending(Patient.GIVEN)
|
||||
.limitTo(100)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
List<String> names = toNameList(resp);
|
||||
|
||||
ourLog.info(StringUtils.join(names, '\n'));
|
||||
|
||||
//@formatter:off
|
||||
assertThat(names, contains( // this matches in order only
|
||||
"Daniel Adams",
|
||||
"Aaron Alexis",
|
||||
"Carol Allen",
|
||||
"Ruth Black",
|
||||
"Brian Brooks",
|
||||
"Amy Clark",
|
||||
"Susan Clark",
|
||||
"Anthony Coleman",
|
||||
"Lisa Coleman",
|
||||
"Steven Coleman",
|
||||
"Ruth Cook",
|
||||
"Betty Davis",
|
||||
"Joshua Diaz",
|
||||
"Brian Gracia",
|
||||
"Sarah Graham",
|
||||
"Stephan Graham"));
|
||||
//@formatter:om
|
||||
|
||||
}
|
||||
|
||||
|
||||
private List<String> toNameList(Bundle resp) {
|
||||
List<String> names = new ArrayList<String>();
|
||||
for (BundleEntry next : resp.getEntries()) {
|
||||
Patient nextPt= (Patient) next.getResource();
|
||||
String nextStr = nextPt.getNameFirstRep().getGivenAsSingleString()+ " " + nextPt.getNameFirstRep().getFamilyAsSingleString();
|
||||
if (isNotBlank(nextStr)) {
|
||||
names.add(nextStr);
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
private void deleteToken(String theResourceType, String theParamName, String theParamSystem, String theParamValue) {
|
||||
Bundle resources = ourClient.search().forResource(theResourceType).where(new TokenClientParam(theParamName).exactly().systemAndCode(theParamSystem, theParamValue)).execute();
|
||||
for (IResource next : resources.toListOfResources()) {
|
||||
|
@ -347,46 +211,34 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testMetaOperations() throws Exception {
|
||||
String methodName = "testMetaOperations";
|
||||
public void testCreateQuestionnaireResponseWithValidation() throws IOException {
|
||||
ValueSet options = new ValueSet();
|
||||
options.getCodeSystem().setSystem("urn:system").addConcept().setCode("code0");
|
||||
IIdType optId = ourClient.create().resource(options).execute().getId();
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addName().addFamily(methodName);
|
||||
IIdType id = ourClient.create().resource(pt).execute().getId().toUnqualifiedVersionless();
|
||||
Questionnaire q = new Questionnaire();
|
||||
q.getGroup().addQuestion().setLinkId("link0").setRequired(false).setType(AnswerFormatEnum.CHOICE).setOptions(new ResourceReferenceDt(optId));
|
||||
IIdType qId = ourClient.create().resource(q).execute().getId();
|
||||
|
||||
MetaDt meta = ourClient.meta().get(MetaDt.class).fromResource(id).execute();
|
||||
assertEquals(0, meta.getTag().size());
|
||||
QuestionnaireResponse qa;
|
||||
|
||||
MetaDt inMeta = new MetaDt();
|
||||
inMeta.addTag().setSystem("urn:system1").setCode("urn:code1");
|
||||
meta = ourClient.meta().add().onResource(id).meta(inMeta).execute();
|
||||
assertEquals(1, meta.getTag().size());
|
||||
// Good code
|
||||
|
||||
inMeta = new MetaDt();
|
||||
inMeta.addTag().setSystem("urn:system1").setCode("urn:code1");
|
||||
meta = ourClient.meta().delete().onResource(id).meta(inMeta).execute();
|
||||
assertEquals(0, meta.getTag().size());
|
||||
qa = new QuestionnaireResponse();
|
||||
qa.getQuestionnaire().setReference(qId.toUnqualifiedVersionless().getValue());
|
||||
qa.getGroup().addQuestion().setLinkId("link0").addAnswer().setValue(new CodingDt().setSystem("urn:system").setCode("code0"));
|
||||
ourClient.create().resource(qa).execute();
|
||||
|
||||
}
|
||||
// Bad code
|
||||
|
||||
@Test
|
||||
public void testGetResourceCountsOperation() throws Exception {
|
||||
String methodName = "testMetaOperations";
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addName().addFamily(methodName);
|
||||
ourClient.create().resource(pt).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
HttpGet get = new HttpGet(ourServerBase + "/$get-resource-counts");
|
||||
CloseableHttpResponse response = ourHttpClient.execute(get);
|
||||
qa = new QuestionnaireResponse();
|
||||
qa.getQuestionnaire().setReference(qId.toUnqualifiedVersionless().getValue());
|
||||
qa.getGroup().addQuestion().setLinkId("link0").addAnswer().setValue(new CodingDt().setSystem("urn:system").setCode("code1"));
|
||||
try {
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
String output = IOUtils.toString(response.getEntity().getContent());
|
||||
IOUtils.closeQuietly(response.getEntity().getContent());
|
||||
ourLog.info(output);
|
||||
assertThat(output, containsString("<parameter><name value=\"Patient\"/><valueInteger value=\""));
|
||||
} finally {
|
||||
response.close();
|
||||
ourClient.create().resource(qa).execute();
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertThat(e.getMessage(), containsString("Question with linkId[link0]"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -427,34 +279,22 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testCreateQuestionnaireResponseWithValidation() throws IOException {
|
||||
ValueSet options = new ValueSet();
|
||||
options.getCodeSystem().setSystem("urn:system").addConcept().setCode("code0");
|
||||
IIdType optId = ourClient.create().resource(options).execute().getId();
|
||||
|
||||
Questionnaire q = new Questionnaire();
|
||||
q.getGroup().addQuestion().setLinkId("link0").setRequired(false).setType(AnswerFormatEnum.CHOICE).setOptions(new ResourceReferenceDt(optId));
|
||||
IIdType qId = ourClient.create().resource(q).execute().getId();
|
||||
public void testCreateResourceReturnsOperationOutcomeByDefault() throws IOException {
|
||||
String resource = "<Patient xmlns=\"http://hl7.org/fhir\"></Patient>";
|
||||
|
||||
QuestionnaireResponse qa;
|
||||
HttpPost post = new HttpPost(ourServerBase + "/Patient");
|
||||
post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
||||
// Good code
|
||||
|
||||
qa = new QuestionnaireResponse();
|
||||
qa.getQuestionnaire().setReference(qId.toUnqualifiedVersionless().getValue());
|
||||
qa.getGroup().addQuestion().setLinkId("link0").addAnswer().setValue(new CodingDt().setSystem("urn:system").setCode("code0"));
|
||||
ourClient.create().resource(qa).execute();
|
||||
|
||||
// Bad code
|
||||
|
||||
qa = new QuestionnaireResponse();
|
||||
qa.getQuestionnaire().setReference(qId.toUnqualifiedVersionless().getValue());
|
||||
qa.getGroup().addQuestion().setLinkId("link0").addAnswer().setValue(new CodingDt().setSystem("urn:system").setCode("code1"));
|
||||
CloseableHttpResponse response = ourHttpClient.execute(post);
|
||||
try {
|
||||
ourClient.create().resource(qa).execute();
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertThat(e.getMessage(), containsString("Question with linkId[link0]"));
|
||||
assertEquals(201, response.getStatusLine().getStatusCode());
|
||||
String respString = IOUtils.toString(response.getEntity().getContent());
|
||||
ourLog.info(response.toString());
|
||||
ourLog.info(respString);
|
||||
assertThat(respString, containsString("<OperationOutcome xmlns=\"http://hl7.org/fhir\">"));
|
||||
} finally {
|
||||
response.getEntity().getContent().close();
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -478,27 +318,6 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateResourceReturnsOperationOutcomeByDefault() throws IOException {
|
||||
String resource = "<Patient xmlns=\"http://hl7.org/fhir\"></Patient>";
|
||||
|
||||
HttpPost post = new HttpPost(ourServerBase + "/Patient");
|
||||
post.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
||||
CloseableHttpResponse response = ourHttpClient.execute(post);
|
||||
try {
|
||||
assertEquals(201, response.getStatusLine().getStatusCode());
|
||||
String respString = IOUtils.toString(response.getEntity().getContent());
|
||||
ourLog.info(response.toString());
|
||||
ourLog.info(respString);
|
||||
assertThat(respString, containsString("<OperationOutcome xmlns=\"http://hl7.org/fhir\">"));
|
||||
} finally {
|
||||
response.getEntity().getContent().close();
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDeepChaining() {
|
||||
delete("Location", Location.SP_NAME, "testDeepChainingL1");
|
||||
|
@ -527,8 +346,8 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
Bundle res = ourClient.search()
|
||||
.forResource(Encounter.class)
|
||||
.where(Encounter.IDENTIFIER.exactly().systemAndCode("urn:foo", "testDeepChainingE1"))
|
||||
.include(Encounter.INCLUDE_LOCATION)
|
||||
.include(Location.INCLUDE_PARTOF)
|
||||
.include(Encounter.INCLUDE_LOCATION.asRecursive())
|
||||
.include(Location.INCLUDE_PARTOF.asRecursive())
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
|
@ -604,8 +423,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
}
|
||||
|
||||
/*
|
||||
* Try it with a raw socket call. The Apache client won't let us use the unescaped "|" in the URL but we want to
|
||||
* make sure that works too..
|
||||
* Try it with a raw socket call. The Apache client won't let us use the unescaped "|" in the URL but we want to make sure that works too..
|
||||
*/
|
||||
Socket sock = new Socket();
|
||||
sock.setSoTimeout(3000);
|
||||
|
@ -845,6 +663,27 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
ourLog.info(ids.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResourceCountsOperation() throws Exception {
|
||||
String methodName = "testMetaOperations";
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addName().addFamily(methodName);
|
||||
ourClient.create().resource(pt).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
HttpGet get = new HttpGet(ourServerBase + "/$get-resource-counts");
|
||||
CloseableHttpResponse response = ourHttpClient.execute(get);
|
||||
try {
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
String output = IOUtils.toString(response.getEntity().getContent());
|
||||
IOUtils.closeQuietly(response.getEntity().getContent());
|
||||
ourLog.info(output);
|
||||
assertThat(output, containsString("<parameter><name value=\"Patient\"/><valueInteger value=\""));
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See issue #52
|
||||
*/
|
||||
|
@ -863,6 +702,29 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaOperations() throws Exception {
|
||||
String methodName = "testMetaOperations";
|
||||
|
||||
Patient pt = new Patient();
|
||||
pt.addName().addFamily(methodName);
|
||||
IIdType id = ourClient.create().resource(pt).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
MetaDt meta = ourClient.meta().get(MetaDt.class).fromResource(id).execute();
|
||||
assertEquals(0, meta.getTag().size());
|
||||
|
||||
MetaDt inMeta = new MetaDt();
|
||||
inMeta.addTag().setSystem("urn:system1").setCode("urn:code1");
|
||||
meta = ourClient.meta().add().onResource(id).meta(inMeta).execute();
|
||||
assertEquals(1, meta.getTag().size());
|
||||
|
||||
inMeta = new MetaDt();
|
||||
inMeta.addTag().setSystem("urn:system1").setCode("urn:code1");
|
||||
meta = ourClient.meta().delete().onResource(id).meta(inMeta).execute();
|
||||
assertEquals(0, meta.getTag().size());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for issue #60
|
||||
*/
|
||||
|
@ -979,7 +841,8 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01");
|
||||
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().execute();
|
||||
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode(null, "testSearchByIdentifierWithoutSystem01")).encodedJson().prettyPrint()
|
||||
.execute();
|
||||
assertEquals(1, actual.size());
|
||||
assertEquals(p1Id.getIdPart(), actual.getEntries().get(0).getResource().getId().getIdPart());
|
||||
|
||||
|
@ -1172,6 +1035,33 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
assertEquals(BundleEntrySearchModeEnum.INCLUDE, found.getEntries().get(1).getResource().getResourceMetadata().get(ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithTextInexactMatch() throws Exception {
|
||||
Observation obs = new Observation();
|
||||
obs.getCode().setText("THIS_IS_THE_TEXT");
|
||||
obs.getCode().addCoding().setSystem("SYSTEM").setCode("CODE").setDisplay("THIS_IS_THE_DISPLAY");
|
||||
ourClient.create().resource(obs).execute();
|
||||
|
||||
testSearchReturnsResults("/Observation?code%3Atext=THIS_IS_THE_TEXT");
|
||||
testSearchReturnsResults("/Observation?code%3Atext=THIS_IS_THE_");
|
||||
testSearchReturnsResults("/Observation?code%3Atext=this_is_the_");
|
||||
testSearchReturnsResults("/Observation?code%3Atext=THIS_IS_THE_DISPLAY");
|
||||
testSearchReturnsResults("/Observation?code%3Atext=THIS_IS_THE_disp");
|
||||
}
|
||||
|
||||
private void testSearchReturnsResults(String search) throws IOException, ClientProtocolException {
|
||||
int matches;
|
||||
HttpGet get = new HttpGet(ourServerBase + search);
|
||||
CloseableHttpResponse response = ourHttpClient.execute(get);
|
||||
String resp = IOUtils.toString(response.getEntity().getContent());
|
||||
IOUtils.closeQuietly(response.getEntity().getContent());
|
||||
ourLog.info(resp);
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle bundle = ourCtx.newXmlParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, resp);
|
||||
matches = bundle.getTotal();
|
||||
|
||||
assertThat(matches, greaterThan(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithMissing() throws Exception {
|
||||
ourLog.info("Starting testSearchWithMissing");
|
||||
|
@ -1242,6 +1132,144 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
assertThat("Wanted " + orgMissing + " but found: " + list, list, containsInRelativeOrder(orgMissing));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithMissing2() throws Exception {
|
||||
checkParamMissing(Observation.SP_CODE);
|
||||
checkParamMissing(Observation.SP_CATEGORY);
|
||||
checkParamMissing(Observation.SP_VALUE_STRING);
|
||||
checkParamMissing(Observation.SP_ENCOUNTER);
|
||||
checkParamMissing(Observation.SP_DATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* See #198
|
||||
*/
|
||||
@Test
|
||||
public void testSortFromResourceProvider() {
|
||||
Patient p;
|
||||
String methodName = "testSortFromResourceProvider";
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Daniel").addFamily("Adams");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Aaron").addFamily("Alexis");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Carol").addFamily("Allen");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Ruth").addFamily("Black");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Brian").addFamily("Brooks");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Susan").addFamily("Clark");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Amy").addFamily("Clark");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Anthony").addFamily("Coleman");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Steven").addFamily("Coleman");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Lisa").addFamily("Coleman");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Ruth").addFamily("Cook");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Betty").addFamily("Davis");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Joshua").addFamily("Diaz");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Brian").addFamily("Gracia");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Stephan").addFamily("Graham");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system").setValue(methodName);
|
||||
p.addName().addGiven("Sarah").addFamily("Graham");
|
||||
ourClient.create().resource(p).execute();
|
||||
|
||||
//@formatter:off
|
||||
Bundle resp = ourClient
|
||||
.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.IDENTIFIER.exactly().systemAndCode("urn:system", methodName))
|
||||
.sort().ascending(Patient.FAMILY)
|
||||
.sort().ascending(Patient.GIVEN)
|
||||
.limitTo(100)
|
||||
.execute();
|
||||
//@formatter:on
|
||||
|
||||
List<String> names = toNameList(resp);
|
||||
|
||||
ourLog.info(StringUtils.join(names, '\n'));
|
||||
|
||||
//@formatter:off
|
||||
assertThat(names, contains( // this matches in order only
|
||||
"Daniel Adams",
|
||||
"Aaron Alexis",
|
||||
"Carol Allen",
|
||||
"Ruth Black",
|
||||
"Brian Brooks",
|
||||
"Amy Clark",
|
||||
"Susan Clark",
|
||||
"Anthony Coleman",
|
||||
"Lisa Coleman",
|
||||
"Steven Coleman",
|
||||
"Ruth Cook",
|
||||
"Betty Davis",
|
||||
"Joshua Diaz",
|
||||
"Brian Gracia",
|
||||
"Sarah Graham",
|
||||
"Stephan Graham"));
|
||||
//@formatter:om
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for issue #60
|
||||
*/
|
||||
|
@ -1578,6 +1606,18 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
return list;
|
||||
}
|
||||
|
||||
private List<String> toNameList(Bundle resp) {
|
||||
List<String> names = new ArrayList<String>();
|
||||
for (BundleEntry next : resp.getEntries()) {
|
||||
Patient nextPt = (Patient) next.getResource();
|
||||
String nextStr = nextPt.getNameFirstRep().getGivenAsSingleString() + " " + nextPt.getNameFirstRep().getFamilyAsSingleString();
|
||||
if (isNotBlank(nextStr)) {
|
||||
names.add(nextStr);
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
ourServer.stop();
|
||||
|
@ -1585,6 +1625,21 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
ourHttpClient.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetadata() throws Exception {
|
||||
HttpGet get = new HttpGet(ourServerBase + "/metadata");
|
||||
CloseableHttpResponse response = ourHttpClient.execute(get);
|
||||
try {
|
||||
String resp = IOUtils.toString(response.getEntity().getContent());
|
||||
ourLog.info(resp);
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
assertThat(resp, stringContainsInOrder("THIS IS THE DESC"));
|
||||
} finally {
|
||||
IOUtils.closeQuietly(response.getEntity().getContent());
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
|
@ -1609,6 +1664,11 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
|
|||
JpaSystemProviderDstu2 systemProv = ourAppCtx.getBean(JpaSystemProviderDstu2.class, "mySystemProviderDstu2");
|
||||
restServer.setPlainProviders(systemProv);
|
||||
|
||||
IFhirSystemDao<ca.uhn.fhir.model.dstu2.resource.Bundle> systemDao = ourAppCtx.getBean(IFhirSystemDao.class);
|
||||
JpaConformanceProviderDstu2 confProvider = new JpaConformanceProviderDstu2(restServer, systemDao);
|
||||
confProvider.setImplementationDescription("THIS IS THE DESC");
|
||||
restServer.setServerConformanceProvider(confProvider);
|
||||
|
||||
restServer.setPagingProvider(new FifoMemoryPagingProvider(10));
|
||||
|
||||
ourServer = new Server(ourPort);
|
||||
|
|
|
@ -314,7 +314,7 @@
|
|||
],
|
||||
"deleted": true,
|
||||
"item": {
|
||||
"reference": "MedicationPrescription/1",
|
||||
"reference": "MedicationOrder/1",
|
||||
"display": "use of Ventolin Inhaler was discontinued"
|
||||
}
|
||||
}
|
||||
|
@ -324,7 +324,7 @@
|
|||
{
|
||||
"base": "urn:uuid:",
|
||||
"resource": {
|
||||
"resourceType": "MedicationPrescription",
|
||||
"resourceType": "MedicationOrder",
|
||||
"id": "124a6916-5d84-4b8c-b250-10cefb8e6e86",
|
||||
"meta": {
|
||||
"lastUpdated": "2013-05-05T16:13:03Z"
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
<appender-ref ref="STDOUT" />
|
||||
</logger>
|
||||
|
||||
<logger name="org.hibernate.SQL" additivity="false" level="trace">
|
||||
<!-- Set to 'trace' to enable SQL logging -->
|
||||
<logger name="org.hibernate.SQL" additivity="false" level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</logger>
|
||||
|
||||
|
|
|
@ -81,14 +81,12 @@
|
|||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf</artifactId>
|
||||
<version>${thymeleaf-version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Used for CORS support -->
|
||||
<dependency>
|
||||
<groupId>org.ebaysf.web</groupId>
|
||||
<artifactId>cors-filter</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
|
@ -101,7 +99,6 @@
|
|||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>4.1.3.RELEASE</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -214,6 +211,7 @@
|
|||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<configuration>
|
||||
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
|
|
|
@ -46,12 +46,10 @@
|
|||
<dependency>
|
||||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-schematron</artifactId>
|
||||
<version>${phloc_schematron_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-commons</artifactId>
|
||||
<version>${phloc_commons_version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--dependency>
|
||||
|
@ -64,63 +62,46 @@
|
|||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>${spring_version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<version>2.3.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.derby</groupId>
|
||||
<artifactId>derby</artifactId>
|
||||
<version>${derby_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.derby</groupId>
|
||||
<artifactId>derbynet</artifactId>
|
||||
<version>${derby_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.derby</groupId>
|
||||
<artifactId>derbyclient</artifactId>
|
||||
<version>${derby_version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf</artifactId>
|
||||
<version>${thymeleaf-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>${slf4j_version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${slf4j_version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava_version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -128,31 +109,26 @@
|
|||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlets</artifactId>
|
||||
<version>${jetty_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
<version>${jetty_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
<version>${jetty_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>${jetty_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-util</artifactId>
|
||||
<version>${jetty_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
package ca.uhn.fhirtest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.hsqldb.Server;
|
||||
import org.hsqldb.persist.HsqlProperties;
|
||||
import org.hsqldb.server.ServerAcl.AclFormatException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
|
||||
public class HsqldbServer implements SmartLifecycle {
|
||||
private final Logger logger = LoggerFactory.getLogger(HsqldbServer.class);
|
||||
private HsqlProperties properties;
|
||||
private Server server;
|
||||
private boolean running = false;
|
||||
|
||||
public HsqldbServer(Properties props) {
|
||||
properties = new HsqlProperties(props);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
if (server != null)
|
||||
server.checkRunning(running);
|
||||
return running;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (server == null) {
|
||||
logger.info("Starting HSQL server...");
|
||||
server = new Server();
|
||||
try {
|
||||
server.setProperties(properties);
|
||||
server.start();
|
||||
running = true;
|
||||
} catch (AclFormatException afe) {
|
||||
logger.error("Error starting HSQL server.", afe);
|
||||
throw new Error(afe);
|
||||
} catch (IOException e) {
|
||||
logger.error("Error starting HSQL server.", e);
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
logger.info("Stopping HSQL server...");
|
||||
if (server != null) {
|
||||
server.stop();
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPhase() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoStartup() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(Runnable runnable) {
|
||||
stop();
|
||||
runnable.run();
|
||||
}
|
||||
}
|
|
@ -24,8 +24,8 @@
|
|||
<properties>
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyTenSevenDialect" />
|
||||
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||
<property name="hibernate.jdbc.batch_size" value="0" />
|
||||
<property name="hibernate.cache.use_minimal_puts" value="false" />
|
||||
<property name="hibernate.jdbc.batch_size" value="20" />
|
||||
<property name="hibernate.cache.use_minimal_puts" value="true" />
|
||||
<property name="hibernate.show_sql" value="false" />
|
||||
<property name="hibernate.cache.use_query_cache" value="false" />
|
||||
<property name="hibernate.cache.use_second_level_cache" value="false" />
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:security="http://www.springframework.org/schema/security"
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:security="http://www.springframework.org/schema/security"
|
||||
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd
|
||||
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
|
||||
|
@ -13,33 +11,19 @@
|
|||
<context:annotation-config />
|
||||
<context:mbean-server />
|
||||
|
||||
<bean depends-on="dbServer" id="myPersistenceDataSource"
|
||||
class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
|
||||
<!-- ;create=true /opt/glassfish/glassfish4/glassfish/nodes/localhost-domain1/fhirtest/fhirdb -->
|
||||
<!-- <property name="url" value="jdbc:hsqldb:hsql://localhost/uhnfhirdb"/> -->
|
||||
<!-- <property name="url" value="jdbc:derby:directory:#{systemproperties['fhir.db.location']};create=true"
|
||||
/> -->
|
||||
<bean depends-on="dbServer" id="myPersistenceDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
|
||||
<property name="driverClassName" value="org.apache.derby.jdbc.ClientDriver"></property>
|
||||
<property name="url"
|
||||
value="jdbc:derby://localhost:1527/#{systemProperties['fhir.db.location.dstu2']};create=true" />
|
||||
<!-- <property name="url" value="jdbc:derby://localhost:1527//opt/glassfish/fhirtest/fhirtest;create=true"
|
||||
/> -->
|
||||
<!--<property name="url" value="jdbc:derby://localhost:1527#{systemProperties['fhir.db.location']};create=true"
|
||||
/> -->
|
||||
<property name="url" value="jdbc:derby://localhost:1527/#{systemProperties['fhir.db.location.dstu2']};create=true" />
|
||||
<property name="username" value="SA" />
|
||||
<property name="password" value="SA" />
|
||||
</bean>
|
||||
|
||||
<!--for mysql -->
|
||||
<!-- <bean depends-on="dbServer" id="myPersistenceDataSource" class="org.apache.commons.dbcp2.BasicDataSource"
|
||||
destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
|
||||
<property name="url" value="jdbc:mysql://fhirdb.url/fhirdbname" /> <property
|
||||
name="username" value="sa"/> <property name="password" value="sa"/> <property
|
||||
name="testOnBorrow" value="true"/> <property name="validationQuery" value="select
|
||||
1;"/> </bean> -->
|
||||
<!-- <bean depends-on="dbServer" id="myPersistenceDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> <property name="driverClassName"
|
||||
value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://fhirdb.url/fhirdbname" /> <property name="username" value="sa"/> <property name="password"
|
||||
value="sa"/> <property name="testOnBorrow" value="true"/> <property name="validationQuery" value="select 1;"/> </bean> -->
|
||||
|
||||
<bean depends-on="dbServer" id="entityManagerFactory"
|
||||
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||
<bean depends-on="dbServer" id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||
<property name="dataSource" ref="myPersistenceDataSource" />
|
||||
<property name="persistenceXmlLocation" value="classpath:META-INF/fhirtest_persistence.xml" />
|
||||
<property name="persistenceUnitName" value="FHIR_UT" />
|
||||
|
@ -48,10 +32,8 @@
|
|||
<property name="showSql" value="false" />
|
||||
<property name="generateDdl" value="true" />
|
||||
<property name="databasePlatform" value="org.hibernate.dialect.DerbyTenSevenDialect" />
|
||||
<!-- <property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect"
|
||||
/> -->
|
||||
<!-- <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"
|
||||
/> -->
|
||||
<!-- <property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" /> -->
|
||||
<!-- <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" /> -->
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
|
|
@ -72,25 +72,21 @@
|
|||
<dependency>
|
||||
<groupId>org.ebaysf.web</groupId>
|
||||
<artifactId>cors-filter</artifactId>
|
||||
<version>${ebay_cors_filter_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf</artifactId>
|
||||
<version>${thymeleaf-version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-schematron</artifactId>
|
||||
<version>${phloc_schematron_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-commons</artifactId>
|
||||
<version>${phloc_commons_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -131,13 +127,8 @@
|
|||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${spring_security_version}</version> <scope>test</scope> </dependency> <dependency>
|
||||
<groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${spring_security_version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-jwt</artifactId> <version>1.0.2.RELEASE</version> <scope>test</scope> </dependency> -->
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -4,6 +4,7 @@ import static org.junit.Assert.*;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -17,6 +18,19 @@ public class IdDtTest {
|
|||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(IdDtTest.class);
|
||||
|
||||
@Test
|
||||
public void testDetectIsIdPartValid() {
|
||||
assertTrue(new IdDt("0").isIdPartValid());
|
||||
assertTrue(new IdDt("0a").isIdPartValid());
|
||||
assertTrue(new IdDt("0abgZZ").isIdPartValid());
|
||||
assertTrue(new IdDt("---").isIdPartValid());
|
||||
assertTrue(new IdDt("1.2.3.4").isIdPartValid());
|
||||
|
||||
assertFalse(new IdDt(" 1").isIdPartValid());
|
||||
assertFalse(new IdDt("1:1").isIdPartValid());
|
||||
assertFalse(new IdDt(StringUtils.leftPad("", 65, '0')).isIdPartValid());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetectLocal() {
|
||||
IdDt id;
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package ca.uhn.fhir.rest.client;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
|
@ -25,9 +28,13 @@ import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
|||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ch.qos.logback.classic.BasicConfigurator;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import ch.qos.logback.classic.joran.JoranConfigurator;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.classic.spi.LoggingEvent;
|
||||
import ch.qos.logback.classic.util.LogbackMDCAdapter;
|
||||
import ch.qos.logback.core.Appender;
|
||||
|
||||
/**
|
||||
|
@ -44,6 +51,7 @@ public class LoggingInterceptorTest {
|
|||
@SuppressWarnings("unchecked")
|
||||
@Before
|
||||
public void before() {
|
||||
|
||||
/*
|
||||
* This is a bit funky, but it's useful for verifying that the headers actually get logged
|
||||
*/
|
||||
|
@ -51,7 +59,7 @@ public class LoggingInterceptorTest {
|
|||
when(myMockAppender.getName()).thenReturn("MOCK");
|
||||
|
||||
org.slf4j.Logger logger = LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
|
||||
|
||||
|
||||
myLoggerRoot = (ch.qos.logback.classic.Logger) logger;
|
||||
myLoggerRoot.addAppender(myMockAppender);
|
||||
}
|
||||
|
@ -86,6 +94,15 @@ public class LoggingInterceptorTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
|
||||
URL conf = LoggingInterceptor.class.getResource("/logback-test-dstuforce.xml");
|
||||
assertNotNull(conf);
|
||||
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||
JoranConfigurator configurator = new JoranConfigurator();
|
||||
configurator.setContext(context);
|
||||
context.reset();
|
||||
configurator.doConfigure(conf);
|
||||
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.junit.Test;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||
|
@ -25,16 +26,72 @@ public class ResourceMethodTest {
|
|||
|
||||
private SearchMethodBinding rm;
|
||||
|
||||
@Search
|
||||
public Bundle foo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() throws NoSuchMethodException, SecurityException {
|
||||
rm = new SearchMethodBinding(Patient.class, ResourceMethodTest.class.getMethod("foo"), FhirContext.forDstu1(), null);
|
||||
}
|
||||
|
||||
@Search
|
||||
public Bundle foo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllParams() {
|
||||
List<IParameter> methodParams = new ArrayList<IParameter>();
|
||||
|
||||
methodParams.add(new SearchParameter("firstName", false));
|
||||
methodParams.add(new SearchParameter("lastName", false));
|
||||
methodParams.add(new SearchParameter("mrn", true));
|
||||
|
||||
rm.setParameters(methodParams);
|
||||
|
||||
Set<String> inputParams = new HashSet<String>();
|
||||
inputParams.add("firstName");
|
||||
inputParams.add("lastName");
|
||||
inputParams.add("mrn");
|
||||
|
||||
RequestDetails params = RequestDetails.withResourceAndParams("Patient", RequestTypeEnum.GET, inputParams);
|
||||
boolean actual = rm.incomingServerRequestMatchesMethod(params);
|
||||
assertTrue( actual); // True
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllParamsWithExtra() {
|
||||
List<IParameter> methodParams = new ArrayList<IParameter>();
|
||||
|
||||
methodParams.add(new SearchParameter("firstName", false));
|
||||
methodParams.add(new SearchParameter("lastName", false));
|
||||
methodParams.add(new SearchParameter("mrn", true));
|
||||
|
||||
rm.setParameters(methodParams);
|
||||
|
||||
Set<String> inputParams = new HashSet<String>();
|
||||
inputParams.add("firstName");
|
||||
inputParams.add("lastName");
|
||||
inputParams.add("mrn");
|
||||
inputParams.add("foo");
|
||||
|
||||
assertEquals(false, rm.incomingServerRequestMatchesMethod(RequestDetails.withResourceAndParams("Patient", RequestTypeEnum.GET, inputParams))); // False
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMixedParams() {
|
||||
List<IParameter> methodParams = new ArrayList<IParameter>();
|
||||
|
||||
methodParams.add(new SearchParameter("firstName", false));
|
||||
methodParams.add(new SearchParameter("lastName", false));
|
||||
methodParams.add(new SearchParameter("mrn", true));
|
||||
|
||||
rm.setParameters(methodParams);
|
||||
|
||||
Set<String> inputParams = new HashSet<String>();
|
||||
inputParams.add("firstName");
|
||||
inputParams.add("mrn");
|
||||
|
||||
assertEquals(true, rm.incomingServerRequestMatchesMethod(RequestDetails.withResourceAndParams("Patient", RequestTypeEnum.GET, inputParams))); // True
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequiredParamsMissing() {
|
||||
List<IParameter> methodParams = new ArrayList<IParameter>();
|
||||
|
@ -67,59 +124,13 @@ public class ResourceMethodTest {
|
|||
assertEquals(true, rm.incomingServerRequestMatchesMethod(RequestDetails.withResourceAndParams("Patient", RequestTypeEnum.GET, inputParams))); // True
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMixedParams() {
|
||||
List<IParameter> methodParams = new ArrayList<IParameter>();
|
||||
|
||||
methodParams.add(new SearchParameter("firstName", false));
|
||||
methodParams.add(new SearchParameter("lastName", false));
|
||||
methodParams.add(new SearchParameter("mrn", true));
|
||||
|
||||
rm.setParameters(methodParams);
|
||||
|
||||
Set<String> inputParams = new HashSet<String>();
|
||||
inputParams.add("firstName");
|
||||
inputParams.add("mrn");
|
||||
|
||||
assertEquals(true, rm.incomingServerRequestMatchesMethod(RequestDetails.withResourceAndParams("Patient", RequestTypeEnum.GET, inputParams))); // True
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testWildcardImmutable() {
|
||||
IResource.INCLUDE_ALL.setValue("AAA");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllParams() {
|
||||
List<IParameter> methodParams = new ArrayList<IParameter>();
|
||||
|
||||
methodParams.add(new SearchParameter("firstName", false));
|
||||
methodParams.add(new SearchParameter("lastName", false));
|
||||
methodParams.add(new SearchParameter("mrn", true));
|
||||
|
||||
rm.setParameters(methodParams);
|
||||
|
||||
Set<String> inputParams = new HashSet<String>();
|
||||
inputParams.add("firstName");
|
||||
inputParams.add("lastName");
|
||||
inputParams.add("mrn");
|
||||
|
||||
RequestDetails params = RequestDetails.withResourceAndParams("Patient", RequestTypeEnum.GET, inputParams);
|
||||
boolean actual = rm.incomingServerRequestMatchesMethod(params);
|
||||
assertTrue( actual); // True
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllParamsWithExtra() {
|
||||
List<IParameter> methodParams = new ArrayList<IParameter>();
|
||||
|
||||
methodParams.add(new SearchParameter("firstName", false));
|
||||
methodParams.add(new SearchParameter("lastName", false));
|
||||
methodParams.add(new SearchParameter("mrn", true));
|
||||
|
||||
rm.setParameters(methodParams);
|
||||
|
||||
Set<String> inputParams = new HashSet<String>();
|
||||
inputParams.add("firstName");
|
||||
inputParams.add("lastName");
|
||||
inputParams.add("mrn");
|
||||
inputParams.add("foo");
|
||||
|
||||
assertEquals(false, rm.incomingServerRequestMatchesMethod(RequestDetails.withResourceAndParams("Patient", RequestTypeEnum.GET, inputParams))); // False
|
||||
public void testWildcardSet() {
|
||||
assertTrue(IResource.WILDCARD_ALL_SET.contains(IResource.INCLUDE_ALL));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<configuration>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%file:%line] - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.eclipse" additivity="false" level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</logger>
|
||||
<logger name="org.apache" additivity="false" level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</logger>
|
||||
<logger name="org.thymeleaf" additivity="false" level="warn">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</logger>
|
||||
|
||||
<!--
|
||||
<logger name="ca.uhn.fhir.rest.client" additivity="false" level="trace">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</logger>
|
||||
-->
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
|
@ -1,5 +1,4 @@
|
|||
<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>
|
||||
|
||||
<parent>
|
||||
|
@ -28,8 +27,7 @@
|
|||
</dependency>
|
||||
|
||||
<!-- Testing -->
|
||||
<!-- <dependency> <groupId>ca.uhn.hapi.fhir</groupId> <artifactId>hapi-fhir-structures-dstu</artifactId>
|
||||
<version>0.8</version> <scope>test</scope> </dependency> -->
|
||||
<!-- <dependency> <groupId>ca.uhn.hapi.fhir</groupId> <artifactId>hapi-fhir-structures-dstu</artifactId> <version>0.8</version> <scope>test</scope> </dependency> -->
|
||||
<dependency>
|
||||
<groupId>xmlunit</groupId>
|
||||
<artifactId>xmlunit</artifactId>
|
||||
|
@ -69,32 +67,27 @@
|
|||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback_version}</version>
|
||||
<optional>true</optional>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ebaysf.web</groupId>
|
||||
<artifactId>cors-filter</artifactId>
|
||||
<version>${ebay_cors_filter_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf</artifactId>
|
||||
<version>${thymeleaf-version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-schematron</artifactId>
|
||||
<version>${phloc_schematron_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-commons</artifactId>
|
||||
<version>${phloc_commons_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -135,15 +128,8 @@
|
|||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava_version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId>
|
||||
<version>${spring_security_version}</version> <scope>test</scope> </dependency>
|
||||
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId>
|
||||
<version>${spring_security_version}</version> <scope>test</scope> </dependency>
|
||||
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-jwt</artifactId>
|
||||
<version>1.0.2.RELEASE</version> <scope>test</scope> </dependency> -->
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
@ -161,122 +147,124 @@
|
|||
</goals>
|
||||
<configuration>
|
||||
<baseResourceNames>
|
||||
<baseResourceName>supplyrequest</baseResourceName>
|
||||
<baseResourceName>supplydelivery</baseResourceName>
|
||||
<baseResourceName>account</baseResourceName>
|
||||
<baseResourceName>allergyintolerance</baseResourceName>
|
||||
<baseResourceName>appointment</baseResourceName>
|
||||
<baseResourceName>appointmentresponse</baseResourceName>
|
||||
<baseResourceName>auditevent</baseResourceName>
|
||||
<baseResourceName>basic</baseResourceName>
|
||||
<baseResourceName>binary</baseResourceName>
|
||||
<baseResourceName>bodysite</baseResourceName>
|
||||
<baseResourceName>bundle</baseResourceName>
|
||||
<baseResourceName>careplan</baseResourceName>
|
||||
<baseResourceName>claim</baseResourceName>
|
||||
<baseResourceName>claimresponse</baseResourceName>
|
||||
<baseResourceName>clinicalimpression</baseResourceName>
|
||||
<baseResourceName>communication</baseResourceName>
|
||||
<baseResourceName>communicationrequest</baseResourceName>
|
||||
<baseResourceName>composition</baseResourceName>
|
||||
<baseResourceName>conceptmap</baseResourceName>
|
||||
<baseResourceName>condition</baseResourceName>
|
||||
<baseResourceName>conformance</baseResourceName>
|
||||
<baseResourceName>contract</baseResourceName>
|
||||
<baseResourceName>contraindication</baseResourceName>
|
||||
<baseResourceName>coverage</baseResourceName>
|
||||
<baseResourceName>dataelement</baseResourceName>
|
||||
<baseResourceName>device</baseResourceName>
|
||||
<baseResourceName>devicecomponent</baseResourceName>
|
||||
<baseResourceName>devicemetric</baseResourceName>
|
||||
<baseResourceName>deviceuserequest</baseResourceName>
|
||||
<baseResourceName>deviceusestatement</baseResourceName>
|
||||
<baseResourceName>diagnosticorder</baseResourceName>
|
||||
<baseResourceName>diagnosticreport</baseResourceName>
|
||||
<baseResourceName>documentation</baseResourceName>
|
||||
<baseResourceName>documentmanifest</baseResourceName>
|
||||
<baseResourceName>documentreference</baseResourceName>
|
||||
<!--<baseResourceName>domainresource</baseResourceName>-->
|
||||
<baseResourceName>eligibilityrequest</baseResourceName>
|
||||
<baseResourceName>eligibilityresponse</baseResourceName>
|
||||
<baseResourceName>encounter</baseResourceName>
|
||||
<baseResourceName>enrollmentrequest</baseResourceName>
|
||||
<baseResourceName>enrollmentresponse</baseResourceName>
|
||||
<baseResourceName>episodeofcare</baseResourceName>
|
||||
<baseResourceName>explanationofbenefit</baseResourceName>
|
||||
<baseResourceName>familymemberhistory</baseResourceName>
|
||||
<baseResourceName>flag</baseResourceName>
|
||||
<baseResourceName>goal</baseResourceName>
|
||||
<baseResourceName>group</baseResourceName>
|
||||
<baseResourceName>healthcareservice</baseResourceName>
|
||||
<baseResourceName>imagingobjectselection</baseResourceName>
|
||||
<baseResourceName>imagingstudy</baseResourceName>
|
||||
<baseResourceName>immunization</baseResourceName>
|
||||
<baseResourceName>immunizationrecommendation</baseResourceName>
|
||||
<baseResourceName>implementationguide</baseResourceName>
|
||||
<baseResourceName>list</baseResourceName>
|
||||
<baseResourceName>location</baseResourceName>
|
||||
<baseResourceName>media</baseResourceName>
|
||||
<baseResourceName>medication</baseResourceName>
|
||||
<baseResourceName>medicationadministration</baseResourceName>
|
||||
<baseResourceName>medicationdispense</baseResourceName>
|
||||
<baseResourceName>medicationorder</baseResourceName>
|
||||
<baseResourceName>medicationstatement</baseResourceName>
|
||||
<baseResourceName>messageheader</baseResourceName>
|
||||
<baseResourceName>namingsystem</baseResourceName>
|
||||
<baseResourceName>nutritionorder</baseResourceName>
|
||||
<baseResourceName>observation</baseResourceName>
|
||||
<baseResourceName>operationdefinition</baseResourceName>
|
||||
<baseResourceName>operationoutcome</baseResourceName>
|
||||
<baseResourceName>order</baseResourceName>
|
||||
<baseResourceName>orderresponse</baseResourceName>
|
||||
<baseResourceName>organization</baseResourceName>
|
||||
<baseResourceName>parameters</baseResourceName>
|
||||
<baseResourceName>patient</baseResourceName>
|
||||
<baseResourceName>paymentnotice</baseResourceName>
|
||||
<baseResourceName>paymentreconciliation</baseResourceName>
|
||||
<baseResourceName>person</baseResourceName>
|
||||
<baseResourceName>practitioner</baseResourceName>
|
||||
<baseResourceName>procedure</baseResourceName>
|
||||
<baseResourceName>procedurerequest</baseResourceName>
|
||||
<baseResourceName>processrequest</baseResourceName>
|
||||
<baseResourceName>processresponse</baseResourceName>
|
||||
<baseResourceName>Condition</baseResourceName>
|
||||
<baseResourceName>DeviceComponent</baseResourceName>
|
||||
<baseResourceName>Communication</baseResourceName>
|
||||
<baseResourceName>Group</baseResourceName>
|
||||
<baseResourceName>ValueSet</baseResourceName>
|
||||
<baseResourceName>Coverage</baseResourceName>
|
||||
<baseResourceName>Appointment</baseResourceName>
|
||||
<baseResourceName>Slot</baseResourceName>
|
||||
<baseResourceName>Contraindication</baseResourceName>
|
||||
<baseResourceName>Composition</baseResourceName>
|
||||
<baseResourceName>EpisodeOfCare</baseResourceName>
|
||||
<baseResourceName>Conformance</baseResourceName>
|
||||
<baseResourceName>NamingSystem</baseResourceName>
|
||||
<baseResourceName>HealthcareService</baseResourceName>
|
||||
<baseResourceName>OrderResponse</baseResourceName>
|
||||
<baseResourceName>ConceptMap</baseResourceName>
|
||||
<baseResourceName>Practitioner</baseResourceName>
|
||||
<baseResourceName>CarePlan</baseResourceName>
|
||||
<baseResourceName>Substance</baseResourceName>
|
||||
<baseResourceName>DeviceUseRequest</baseResourceName>
|
||||
<baseResourceName>Schedule</baseResourceName>
|
||||
<baseResourceName>EligibilityRequest</baseResourceName>
|
||||
<baseResourceName>QuestionnaireResponse</baseResourceName>
|
||||
<baseResourceName>PaymentReconciliation</baseResourceName>
|
||||
<baseResourceName>ImagingObjectSelection</baseResourceName>
|
||||
<baseResourceName>OperationDefinition</baseResourceName>
|
||||
<baseResourceName>ClaimResponse</baseResourceName>
|
||||
<baseResourceName>BodySite</baseResourceName>
|
||||
<baseResourceName>CommunicationRequest</baseResourceName>
|
||||
<baseResourceName>RiskAssessment</baseResourceName>
|
||||
<baseResourceName>Observation</baseResourceName>
|
||||
<baseResourceName>AllergyIntolerance</baseResourceName>
|
||||
<baseResourceName>ExplanationOfBenefit</baseResourceName>
|
||||
<baseResourceName>RelatedPerson</baseResourceName>
|
||||
<baseResourceName>AuditEvent</baseResourceName>
|
||||
<baseResourceName>EligibilityResponse</baseResourceName>
|
||||
<baseResourceName>Person</baseResourceName>
|
||||
<baseResourceName>ProcedureRequest</baseResourceName>
|
||||
<baseResourceName>ProcessRequest</baseResourceName>
|
||||
<baseResourceName>Claim</baseResourceName>
|
||||
<baseResourceName>DeviceMetric</baseResourceName>
|
||||
<baseResourceName>Organization</baseResourceName>
|
||||
<baseResourceName>ImmunizationRecommendation</baseResourceName>
|
||||
<baseResourceName>MedicationDispense</baseResourceName>
|
||||
<baseResourceName>MedicationPrescription</baseResourceName>
|
||||
<baseResourceName>PaymentNotice</baseResourceName>
|
||||
<baseResourceName>MedicationStatement</baseResourceName>
|
||||
<baseResourceName>AppointmentResponse</baseResourceName>
|
||||
<baseResourceName>Questionnaire</baseResourceName>
|
||||
<baseResourceName>OperationOutcome</baseResourceName>
|
||||
<baseResourceName>Media</baseResourceName>
|
||||
<baseResourceName>Binary</baseResourceName>
|
||||
<baseResourceName>VisionPrescription</baseResourceName>
|
||||
<baseResourceName>DocumentReference</baseResourceName>
|
||||
<baseResourceName>Immunization</baseResourceName>
|
||||
<baseResourceName>Bundle</baseResourceName>
|
||||
<baseResourceName>Subscription</baseResourceName>
|
||||
<baseResourceName>ImagingStudy</baseResourceName>
|
||||
<baseResourceName>Provenance</baseResourceName>
|
||||
<baseResourceName>Device</baseResourceName>
|
||||
<baseResourceName>StructureDefinition</baseResourceName>
|
||||
<baseResourceName>Order</baseResourceName>
|
||||
<baseResourceName>Procedure</baseResourceName>
|
||||
<baseResourceName>DiagnosticReport</baseResourceName>
|
||||
<baseResourceName>Medication</baseResourceName>
|
||||
<baseResourceName>MessageHeader</baseResourceName>
|
||||
<baseResourceName>DataElement</baseResourceName>
|
||||
<baseResourceName>DocumentManifest</baseResourceName>
|
||||
<baseResourceName>MedicationAdministration</baseResourceName>
|
||||
<baseResourceName>Encounter</baseResourceName>
|
||||
<baseResourceName>List</baseResourceName>
|
||||
<baseResourceName>DeviceUseStatement</baseResourceName>
|
||||
<baseResourceName>Goal</baseResourceName>
|
||||
<baseResourceName>NutritionOrder</baseResourceName>
|
||||
<baseResourceName>SearchParameter</baseResourceName>
|
||||
<baseResourceName>ReferralRequest</baseResourceName>
|
||||
<baseResourceName>EnrollmentRequest</baseResourceName>
|
||||
<baseResourceName>Location</baseResourceName>
|
||||
<baseResourceName>Contract</baseResourceName>
|
||||
<baseResourceName>Basic</baseResourceName>
|
||||
<baseResourceName>Specimen</baseResourceName>
|
||||
<baseResourceName>EnrollmentResponse</baseResourceName>
|
||||
<baseResourceName>Patient</baseResourceName>
|
||||
<baseResourceName>DiagnosticOrder</baseResourceName>
|
||||
<baseResourceName>Parameters</baseResourceName>
|
||||
<!--<baseResourceName>protocol</baseResourceName>-->
|
||||
<baseResourceName>provenance</baseResourceName>
|
||||
<baseResourceName>questionnaire</baseResourceName>
|
||||
<baseResourceName>questionnaireresponse</baseResourceName>
|
||||
<baseResourceName>referralrequest</baseResourceName>
|
||||
<baseResourceName>relatedperson</baseResourceName>
|
||||
<baseResourceName>remittance</baseResourceName>
|
||||
<!--<baseResourceName>resource</baseResourceName>-->
|
||||
<baseResourceName>riskassessment</baseResourceName>
|
||||
|
||||
<baseResourceName>schedule</baseResourceName>
|
||||
<baseResourceName>searchparameter</baseResourceName>
|
||||
<baseResourceName>slot</baseResourceName>
|
||||
<baseResourceName>specimen</baseResourceName>
|
||||
<baseResourceName>structuredefinition</baseResourceName>
|
||||
<baseResourceName>subscription</baseResourceName>
|
||||
<baseResourceName>substance</baseResourceName>
|
||||
<baseResourceName>supplydelivery</baseResourceName>
|
||||
<baseResourceName>supplyrequest</baseResourceName>
|
||||
<baseResourceName>supportingdocumentation</baseResourceName>
|
||||
<!--<baseResourceName>template</baseResourceName>-->
|
||||
<baseResourceName>test</baseResourceName>
|
||||
<baseResourceName>testscript</baseResourceName>
|
||||
<baseResourceName>user</baseResourceName>
|
||||
<baseResourceName>valueset</baseResourceName>
|
||||
<baseResourceName>visionprescription</baseResourceName>
|
||||
</baseResourceNames>
|
||||
<package>ca.uhn.fhir.model.dstu2</package>
|
||||
<version>dstu2</version>
|
||||
<buildDatatypes>true</buildDatatypes>
|
||||
</configuration>
|
||||
</execution>
|
||||
<!--
|
||||
<execution>
|
||||
<id>clean_source</id>
|
||||
<goals>
|
||||
<goal>minimize-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<fhirVersion>DSTU2</fhirVersion>
|
||||
<targetDirectory>${project.baseDir}/../hapi-tinder-plugin/</targetDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
-->
|
||||
<!-- <execution> <id>clean_source</id> <goals> <goal>minimize-resources</goal> </goals> <configuration> <fhirVersion>DSTU2</fhirVersion> <targetDirectory>${project.baseDir}/../hapi-tinder-plugin/</targetDirectory>
|
||||
</configuration> </execution> -->
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<!--This plugin's configuration is used to store Eclipse m2e settings
|
||||
only. It has no influence on the Maven build itself. -->
|
||||
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself. -->
|
||||
<plugin>
|
||||
<groupId>org.eclipse.m2e</groupId>
|
||||
<artifactId>lifecycle-mapping</artifactId>
|
||||
|
|
|
@ -23,7 +23,7 @@ import ca.uhn.fhir.model.dstu2.composite.QuantityDt;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
@DatatypeDef(name="MoneyDt")
|
||||
@DatatypeDef(name="Money")
|
||||
public class MoneyDt extends QuantityDt {
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
package ca.uhn.fhir.model.dstu2.composite;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||
import ca.uhn.fhir.model.api.annotation.SimpleSetter;
|
||||
import ca.uhn.fhir.model.dstu2.composite.QuantityDt;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.QuantityComparatorEnum;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR Structures - DSTU2 (FHIR v0.5.0)
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2015 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
@DatatypeDef(name="SimpleQuantity")
|
||||
public class SimpleQuantityDt extends QuantityDt {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public SimpleQuantityDt() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
@SimpleSetter
|
||||
public SimpleQuantityDt(@SimpleSetter.Parameter(name="theValue") double theValue) {
|
||||
setValue(theValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
@SimpleSetter
|
||||
public SimpleQuantityDt(@SimpleSetter.Parameter(name="theValue") long theValue) {
|
||||
setValue(theValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
@SimpleSetter
|
||||
public SimpleQuantityDt(@SimpleSetter.Parameter(name = "theComparator") QuantityComparatorEnum theComparator, @SimpleSetter.Parameter(name = "theValue") double theValue,
|
||||
@SimpleSetter.Parameter(name = "theUnits") String theUnits) {
|
||||
setValue(theValue);
|
||||
setComparator(theComparator);
|
||||
setUnit(theUnits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
@SimpleSetter
|
||||
public SimpleQuantityDt(@SimpleSetter.Parameter(name = "theComparator") QuantityComparatorEnum theComparator, @SimpleSetter.Parameter(name = "theValue") long theValue,
|
||||
@SimpleSetter.Parameter(name = "theUnits") String theUnits) {
|
||||
setValue(theValue);
|
||||
setComparator(theComparator);
|
||||
setUnit(theUnits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
@SimpleSetter
|
||||
public SimpleQuantityDt(@SimpleSetter.Parameter(name="theValue") double theValue, @SimpleSetter.Parameter(name="theSystem") String theSystem, @SimpleSetter.Parameter(name="theUnits") String theUnits) {
|
||||
setValue(theValue);
|
||||
setSystem(theSystem);
|
||||
setUnit(theUnits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
@SimpleSetter
|
||||
public SimpleQuantityDt(@SimpleSetter.Parameter(name="theValue") long theValue, @SimpleSetter.Parameter(name="theSystem") String theSystem, @SimpleSetter.Parameter(name="theUnits") String theUnits) {
|
||||
setValue(theValue);
|
||||
setSystem(theSystem);
|
||||
setUnit(theUnits);
|
||||
}
|
||||
|
||||
}
|
|
@ -10,45 +10,45 @@
|
|||
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>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>Account</sch:title>
|
||||
<sch:rule context="f:Account">
|
||||
<sch:rule context="//f:Account">
|
||||
<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:Account/f:text/f:div">
|
||||
<sch:rule context="//f:Account/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Account/f:identifier/f:period">
|
||||
<sch:rule context="//f:Account/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Account/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:Account/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Account/f:activePeriod">
|
||||
<sch:rule context="//f:Account/f:activePeriod">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Account/f:balance">
|
||||
<sch:rule context="//f:Account/f:balance">
|
||||
<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:Account/f:coveragePeriod">
|
||||
<sch:rule context="//f:Account/f:coveragePeriod">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Account/f:subject">
|
||||
<sch:rule context="//f:Account/f:subject">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Account/f:owner">
|
||||
<sch:rule context="//f:Account/f:owner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,42 +10,45 @@
|
|||
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>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">
|
||||
<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:rule context="//f:AllergyIntolerance/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:AllergyIntolerance/f:identifier/f:period">
|
||||
<sch:rule context="//f:AllergyIntolerance/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:AllergyIntolerance/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:AllergyIntolerance/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:AllergyIntolerance/f:recorder">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:AllergyIntolerance/f:patient">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:AllergyIntolerance/f:reporter">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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: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 context="//f:AllergyIntolerance/f:notes/f:authorReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:rule context="//f:AllergyIntolerance/f:reaction/f:notes/f:authorReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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>
|
||||
|
|
|
@ -10,39 +10,44 @@
|
|||
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>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">
|
||||
<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:assert test="(not((f:status/@value='proposed') or (f:status/@value='cancelled')) and exists(f:start) and exists(f:end))">app-3: Only proposed or cancelled appointments can be missing start/end dates</sch:assert>
|
||||
<sch:assert test="((exists(f:start) and exists(f:end)) or (not(exists(f:start)) and not(exists(f:end))))">app-2: Either start and end are specified, or neither</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Appointment/f:text/f:div">
|
||||
<sch:rule context="//f:Appointment/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Appointment/f:identifier/f:period">
|
||||
<sch:rule context="//f:Appointment/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Appointment/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:Appointment/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:slot">
|
||||
<sch:rule context="//f:Appointment/f:slot">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Appointment/f:order">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:actor">
|
||||
<sch:rule context="//f:Appointment/f:participant">
|
||||
<sch:assert test="(exists(f:type) or exists(f:actor))">app-1: Either the type or actor on the participant MUST be specified</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::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,36 +10,37 @@
|
|||
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>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">
|
||||
<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:assert test="(exists(f:type) or exists(f:actor))">apr-1: Either the type or actor on the participant should be specified</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:AppointmentResponse/f:text/f:div">
|
||||
<sch:rule context="//f:AppointmentResponse/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:AppointmentResponse/f:identifier/f:period">
|
||||
<sch:rule context="//f:AppointmentResponse/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:AppointmentResponse/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:AppointmentResponse/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:AppointmentResponse/f:appointment">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:actor">
|
||||
<sch:rule context="//f:AppointmentResponse/f:actor">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,46 +10,54 @@
|
|||
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>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">
|
||||
<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:rule context="//f:AuditEvent/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:AuditEvent/f: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:reference">
|
||||
<sch:rule context="//f:AuditEvent/f:participant/f:reference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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">
|
||||
<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:period">
|
||||
<sch:rule context="//f:AuditEvent/f:participant/f:userId/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:AuditEvent/f:object/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:AuditEvent/f:participant/f:userId/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:AuditEvent/f:participant/f:location">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:rule context="//f:AuditEvent/f:source/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="//f:AuditEvent/f:source/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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">
|
||||
<sch:assert test="not(exists(f:name)) or not(exists(f:query))">sev-1: Either a name or a query (NOT both)</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="//f:AuditEvent/f:object/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="//f:AuditEvent/f:object/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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>
|
||||
|
|
|
@ -10,36 +10,36 @@
|
|||
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>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">
|
||||
<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:rule context="//f:Basic/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Basic/f:identifier/f:period">
|
||||
<sch:rule context="//f:Basic/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Basic/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:Basic/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:subject">
|
||||
<sch:rule context="//f:Basic/f:subject">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Basic/f:author">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,13 +10,13 @@
|
|||
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>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:pattern>
|
||||
</sch:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,36 +10,36 @@
|
|||
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>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">
|
||||
<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:rule context="//f:BodySite/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:BodySite/f:patient">
|
||||
<sch:rule context="//f:BodySite/f:patient">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:period">
|
||||
<sch:rule context="//f:BodySite/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:BodySite/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:BodySite/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:image">
|
||||
<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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,27 +10,27 @@
|
|||
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>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">
|
||||
<sch:rule context="//f:Bundle">
|
||||
<sch:assert test="count(for $entry in entry[resource] return $entry[count(parent::Bundle/entry[fullUrl/@value=$entry/fullUrl/@value and resource/*/meta/versionId/@value=$entry/resource/*/meta/versionId/@value])!=1])=0">bdl-7: FullUrl must be unique in a bundle, or else entries with the same fullUrl must have different meta.versionId</sch:assert>
|
||||
<sch:assert test="not(f:entry/f:request) or (f:type/@value = 'batch') 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:response) or (f:type/@value = 'batch-response') 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:rule context="//f:Bundle/f:entry">
|
||||
<sch:assert test="f:resource or f:request or f:response">bdl-5: must be a resource unless there's a transaction or transaction response</sch:assert>
|
||||
<sch:assert test="(not(exists(f:fullUrl)) and not(exists(f:resource))) or (exists(f:fullUrl) and exists(f:resource))">bdl-6: The fullUrl element must be present when a resource is present, and not present otherwise</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Bundle/f:signature/f:whoReference">
|
||||
<sch:rule context="//f:Bundle/f:signature/f:whoReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,115 +10,114 @@
|
|||
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>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">
|
||||
<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:rule context="//f:CarePlan/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:CarePlan/f:identifier/f:period">
|
||||
<sch:rule context="//f:CarePlan/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:CarePlan/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:CarePlan/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:CarePlan/f:patient">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:CarePlan/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:CarePlan/f:author">
|
||||
<sch:rule context="//f:CarePlan/f:author">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:concern">
|
||||
<sch:rule context="//f:CarePlan/f:concern">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:CarePlan/f:support">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:member">
|
||||
<sch:rule context="//f:CarePlan/f:participant/f:member">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:CarePlan/f:goal">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:CarePlan/f:activity/f:actionResulting">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:CarePlan/f:activity/f:reference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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: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:reasonReference">
|
||||
<sch:rule context="//f:CarePlan/f:activity/f:detail/f:reasonReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:CarePlan/f:activity/f:detail/f:goal">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:scheduledTiming/f:repeat">
|
||||
<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:boundsDuration">
|
||||
<sch:rule context="//f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:boundsDuration">
|
||||
<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:scheduledTiming/f:repeat/f:boundsRange">
|
||||
<sch:rule context="//f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:boundsRange">
|
||||
<sch:assert test="not(exists(f:low/f:value/@value)) or not(exists(f:high/f:value/@value)) or (number(f:low/f:value/@value) <= number(f:high/f:value/@value))">rng-2: If present, low SHALL have a lower value than high</sch:assert>
|
||||
<sch:assert test="not(exists(f:low/f:comparator) or exists(f:high/f:comparator))">rng-3: Quantity values cannot have a comparator when used in a Range</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:boundsRange/f:low">
|
||||
<sch:rule context="//f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:boundsRange/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:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:boundsRange/f:high">
|
||||
<sch:rule context="//f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:boundsRange/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:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:boundsPeriod">
|
||||
<sch:rule context="//f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:boundsPeriod">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:duration">
|
||||
<sch:rule context="//f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:duration">
|
||||
<sch:assert test="@value >= 0 or not(@value)">tim-4: duration SHALL be a non-negative value</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:period">
|
||||
<sch:rule context="//f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:period">
|
||||
<sch:assert test="@value >= 0 or not(@value)">tim-5: period SHALL be a non-negative value</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledPeriod">
|
||||
<sch:rule context="//f:CarePlan/f:activity/f:detail/f:scheduledPeriod">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:CarePlan/f:activity/f:detail/f:location">
|
||||
<sch:rule context="//f:CarePlan/f:activity/f:detail/f:location">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:CarePlan/f:activity/f:detail/f:performer">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:CarePlan/f:activity/f:detail/f:product">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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: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: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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<?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"/>
|
||||
<sch:pattern>
|
||||
<sch:title>Observation</sch:title>
|
||||
<sch:rule context="f:Cholesterol">
|
||||
<sch:assert test="count(f:referenceRange) >= 1">referenceRange: minimum cardinality is 1</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Cholesterol">
|
||||
<sch:assert test="count(f:referenceRange) <= 1">referenceRange: maximum cardinality is 1</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Cholesterol">
|
||||
<sch:assert test="count(f:related) <= 0">related: maximum cardinality is 0</sch:assert>
|
||||
</sch:rule>
|
||||
</sch:pattern>
|
||||
<sch:pattern>
|
||||
<sch:title>Observation.valueQuantity</sch:title>
|
||||
<sch:rule context="f:Cholesterol/f:valueQuantity">
|
||||
<sch:assert test="count(f:comparator) <= 0">comparator: maximum cardinality is 0</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Cholesterol/f:valueQuantity">
|
||||
<sch:assert test="count(f:unit) >= 1">unit: minimum cardinality is 1</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Cholesterol/f:valueQuantity">
|
||||
<sch:assert test="count(f:system) >= 1">system: minimum cardinality is 1</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Cholesterol/f:valueQuantity">
|
||||
<sch:assert test="count(f:code) >= 1">code: minimum cardinality is 1</sch:assert>
|
||||
</sch:rule>
|
||||
</sch:pattern>
|
||||
<sch:pattern>
|
||||
<sch:title>Observation.referenceRange</sch:title>
|
||||
<sch:rule context="f:Cholesterol/f:referenceRange">
|
||||
<sch:assert test="count(f:low) <= 0">low: maximum cardinality is 0</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Cholesterol/f:referenceRange">
|
||||
<sch:assert test="count(f:high) >= 1">high: minimum cardinality is 1</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Cholesterol/f:referenceRange">
|
||||
<sch:assert test="count(f:meaning) <= 0">meaning: maximum cardinality is 0</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Cholesterol/f:referenceRange">
|
||||
<sch:assert test="count(f:age) <= 0">age: maximum cardinality is 0</sch:assert>
|
||||
</sch:rule>
|
||||
</sch:pattern>
|
||||
</sch:schema>
|
|
@ -10,102 +10,102 @@
|
|||
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>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">
|
||||
<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:rule context="//f:Claim/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Claim/f:identifier/f:period">
|
||||
<sch:rule context="//f:Claim/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Claim/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:Claim/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:target">
|
||||
<sch:rule context="//f:Claim/f:target">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Claim/f:provider">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Claim/f:organization">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:enterer">
|
||||
<sch:rule context="//f:Claim/f:enterer">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Claim/f:facility">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Claim/f:prescription">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Claim/f:originalPrescription">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:provider">
|
||||
<sch:rule context="//f:Claim/f:payee/f:provider">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Claim/f:payee/f:organization">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Claim/f:payee/f:person">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Claim/f:referral">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:patient">
|
||||
<sch:rule context="//f:Claim/f:patient">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Claim/f:coverage/f:coverage">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:claimResponse">
|
||||
<sch:rule context="//f:Claim/f:coverage/f:claimResponse">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:provider">
|
||||
<sch:rule context="//f:Claim/f:item/f:provider">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:quantity">
|
||||
<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: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: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:detail/f:quantity">
|
||||
<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: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: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:subDetail/f:quantity">
|
||||
<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: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: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:pattern>
|
||||
</sch:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,90 +10,90 @@
|
|||
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>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">
|
||||
<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:rule context="//f:ClaimResponse/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:ClaimResponse/f:identifier/f:period">
|
||||
<sch:rule context="//f:ClaimResponse/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:ClaimResponse/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:ClaimResponse/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:ClaimResponse/f:request">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:organization">
|
||||
<sch:rule context="//f:ClaimResponse/f:organization">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:ClaimResponse/f:requestProvider">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:ClaimResponse/f:requestOrganization">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:item/f:adjudication/f:amount">
|
||||
<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:amount">
|
||||
<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:amount">
|
||||
<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:fee">
|
||||
<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:amount">
|
||||
<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:fee">
|
||||
<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:amount">
|
||||
<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:totalCost">
|
||||
<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: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: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: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:paymentAmount">
|
||||
<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:period">
|
||||
<sch:rule context="//f:ClaimResponse/f:paymentRef/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:ClaimResponse/f:paymentRef/f:assigner">
|
||||
<sch:rule context="//f:ClaimResponse/f:paymentRef/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:coverage">
|
||||
<sch:rule context="//f:ClaimResponse/f:coverage/f:coverage">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:claimResponse">
|
||||
<sch:rule context="//f:ClaimResponse/f:coverage/f:claimResponse">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<?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"/>
|
||||
</sch:schema>
|
|
@ -10,48 +10,48 @@
|
|||
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>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">
|
||||
<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:rule context="//f:ClinicalImpression/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:ClinicalImpression/f:patient">
|
||||
<sch:rule context="//f:ClinicalImpression/f:patient">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:ClinicalImpression/f:assessor">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:ClinicalImpression/f:previous">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:ClinicalImpression/f:problem">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:triggerReference">
|
||||
<sch:rule context="//f:ClinicalImpression/f:triggerReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:item">
|
||||
<sch:rule context="//f:ClinicalImpression/f:investigations/f:item">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:plan">
|
||||
<sch:rule context="//f:ClinicalImpression/f:plan">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:ClinicalImpression/f:action">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,48 +10,48 @@
|
|||
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>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">
|
||||
<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:rule context="//f:Communication/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Communication/f:identifier/f:period">
|
||||
<sch:rule context="//f:Communication/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Communication/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:Communication/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:sender">
|
||||
<sch:rule context="//f:Communication/f:sender">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Communication/f:recipient">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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: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:rule context="//f:Communication/f:payload/f:contentReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:encounter">
|
||||
<sch:rule context="//f:Communication/f:encounter">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:subject">
|
||||
<sch:rule context="//f:Communication/f:subject">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,51 +10,51 @@
|
|||
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>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">
|
||||
<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:rule context="//f:CommunicationRequest/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:CommunicationRequest/f:identifier/f:period">
|
||||
<sch:rule context="//f:CommunicationRequest/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:CommunicationRequest/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:CommunicationRequest/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:sender">
|
||||
<sch:rule context="//f:CommunicationRequest/f:sender">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:CommunicationRequest/f:recipient">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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: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:rule context="//f:CommunicationRequest/f:payload/f:contentReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:requester">
|
||||
<sch:rule context="//f:CommunicationRequest/f:requester">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:CommunicationRequest/f:encounter">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:subject">
|
||||
<sch:rule context="//f:CommunicationRequest/f:subject">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,63 +10,63 @@
|
|||
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>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">
|
||||
<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:rule context="//f:Composition/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Composition/f:identifier/f:period">
|
||||
<sch:rule context="//f:Composition/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Composition/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:Composition/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:subject">
|
||||
<sch:rule context="//f:Composition/f:subject">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Composition/f:author">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Composition/f:attester/f:party">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Composition/f:custodian">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:period">
|
||||
<sch:rule context="//f:Composition/f:event/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Composition/f:event/f:detail">
|
||||
<sch:rule context="//f:Composition/f:event/f:detail">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Composition/f:encounter">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Composition/f:section">
|
||||
<sch:assert test="exists(f:text) or exists(f:entry) or exists(f:section)">cmp-1: A section must at least one of text, entries, or sub-sections</sch:assert>
|
||||
<sch:assert test="not(exists(f:emptyReason) and exists(f:entry))">cmp-2: A section can only have an emptyReason if it is empty</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Composition/f:section/f:text/f:div">
|
||||
<sch:rule context="//f:Composition/f:section/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Composition/f:section/f:entry">
|
||||
<sch:rule context="//f:Composition/f:section/f:entry">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,45 +10,45 @@
|
|||
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>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">
|
||||
<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:rule context="//f:ConceptMap/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:ConceptMap/f:identifier/f:period">
|
||||
<sch:rule context="//f:ConceptMap/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:ConceptMap/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:ConceptMap/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:contact/f:telecom">
|
||||
<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:rule context="//f:ConceptMap/f:contact/f:telecom/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:ConceptMap/f:sourceReference">
|
||||
<sch:rule context="//f:ConceptMap/f:sourceReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:ConceptMap/f:targetReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:target">
|
||||
<sch:rule context="//f:ConceptMap/f:element/f:target">
|
||||
<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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,83 +10,81 @@
|
|||
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>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">
|
||||
<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:rule context="//f:Condition/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Condition/f:identifier/f:period">
|
||||
<sch:rule context="//f:Condition/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Condition/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:Condition/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Condition/f:patient">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Condition/f:encounter">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Condition/f:asserter">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:onsetAge">
|
||||
<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:rule context="//f:Condition/f:onsetPeriod">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Condition/f:onsetRange">
|
||||
<sch:rule context="//f:Condition/f:onsetRange">
|
||||
<sch:assert test="not(exists(f:low/f:value/@value)) or not(exists(f:high/f:value/@value)) or (number(f:low/f:value/@value) <= number(f:high/f:value/@value))">rng-2: If present, low SHALL have a lower value than high</sch:assert>
|
||||
<sch:assert test="not(exists(f:low/f:comparator) or exists(f:high/f:comparator))">rng-3: Quantity values cannot have a comparator when used in a Range</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Condition/f:onsetRange/f:low">
|
||||
<sch: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: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: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:rule context="//f:Condition/f:abatementPeriod">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Condition/f:abatementRange">
|
||||
<sch:rule context="//f:Condition/f:abatementRange">
|
||||
<sch:assert test="not(exists(f:low/f:value/@value)) or not(exists(f:high/f:value/@value)) or (number(f:low/f:value/@value) <= number(f:high/f:value/@value))">rng-2: If present, low SHALL have a lower value than high</sch:assert>
|
||||
<sch:assert test="not(exists(f:low/f:comparator) or exists(f:high/f:comparator))">rng-3: Quantity values cannot have a comparator when used in a Range</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Condition/f:abatementRange/f:low">
|
||||
<sch: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: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: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:assessment">
|
||||
<sch:rule context="//f:Condition/f:stage/f:assessment">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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: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:detail">
|
||||
<sch:rule context="//f:Condition/f:evidence/f:detail">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,26 +10,19 @@
|
|||
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>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">
|
||||
<sch:rule context="//f:Conformance">
|
||||
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL NOT contain nested Resources</sch:assert>
|
||||
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL NOT contain any narrative</sch:assert>
|
||||
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL NOT have a meta.versionId or a meta.lastUpdated</sch:assert>
|
||||
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Conformance/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Conformance">
|
||||
<sch:assert test="count(f:rest)=count(distinct-values(f:rest/f:mode/@value))">cnf-8: There can only be one REST declaration per mode</sch:assert>
|
||||
<sch:assert test="count(f:document[f:mode='producer'])=count(distinct-values(f:document[f:mode='producer']/f:profile/@value)) and count(f:document[f:mode='consumer'])=count(distinct-values(f:document[f:mode='consumer']/f:profile/@value))">cnf-7: The set of documents must be unique by the combination of profile & mode</sch:assert>
|
||||
<sch:assert test="count(f:software | f:implementation | f:description) > 0">cnf-2: A Conformance statement SHALL have at least one of description, software, or implementation</sch:assert>
|
||||
|
@ -37,43 +30,48 @@
|
|||
<sch:assert test="not(exists(f:software) or exists(f:implementation)) or (f:kind/@value != 'requirements')">cnf-14: Conformance statements of kind 'requirements' do not have software or implementation elements</sch:assert>
|
||||
<sch:assert test="not(exists(f:implementation)) or (f:kind/@value != 'capability')">cnf-15: Conformance statements of kind 'software' do not have implementation elements</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Conformance/f:contact/f:telecom">
|
||||
<sch:rule context="//f:Conformance/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="//f:Conformance/f: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:rule context="//f:Conformance/f:contact/f:telecom/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Conformance/f:profile">
|
||||
<sch:rule context="//f:Conformance/f:profile">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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: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:resource">
|
||||
<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:rule context="//f:Conformance/f:rest/f:resource/f:profile">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:resource/f:searchParam">
|
||||
<sch:rule context="//f:Conformance/f:rest/f:resource/f:searchParam">
|
||||
<sch:assert test="not(exists(f:chain)) or (f:type/@value = 'reference')">cnf-13: Search parameters can only have chain names when the search parameter type is 'reference'</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Conformance/f:rest/f:operation/f:definition">
|
||||
<sch:rule context="//f:Conformance/f:rest/f:operation/f:definition">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Conformance/f:messaging">
|
||||
<sch:assert test="exists(f:endpoint) = (f:kind/@value = '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:request">
|
||||
<sch:rule context="//f:Conformance/f:messaging/f:event/f:request">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Conformance/f:messaging/f:event/f:response">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Conformance/f:document/f:profile">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<?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"/>
|
||||
<sch:pattern>
|
||||
<sch:title>Contract</sch:title>
|
||||
<sch:rule context="f:ConsentDirective">
|
||||
<sch:assert test="count(f:valuedItem) <= 0">valuedItem: maximum cardinality is 0</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:ConsentDirective">
|
||||
<sch:assert test="count(f:binding[x]) >= 1">binding[x]: minimum cardinality is 1</sch:assert>
|
||||
</sch:rule>
|
||||
</sch:pattern>
|
||||
<sch:pattern>
|
||||
<sch:title>Contract.term</sch:title>
|
||||
<sch:rule context="f:ConsentDirective/f:term">
|
||||
<sch:assert test="count(f:valuedItem) <= 0">valuedItem: maximum cardinality is 0</sch:assert>
|
||||
</sch:rule>
|
||||
</sch:pattern>
|
||||
</sch:schema>
|
|
@ -10,123 +10,123 @@
|
|||
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>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">
|
||||
<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:rule context="//f:Contract/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Contract/f:identifier/f:period">
|
||||
<sch:rule context="//f:Contract/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Contract/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:Contract/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Contract/f:applies">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Contract/f:subject">
|
||||
<sch:rule context="//f:Contract/f:subject">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Contract/f:authority">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Contract/f:domain">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:entity">
|
||||
<sch:rule context="//f:Contract/f:actor/f:entity">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:entityReference">
|
||||
<sch:rule context="//f:Contract/f:valuedItem/f:entityReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:period">
|
||||
<sch:rule context="//f:Contract/f:valuedItem/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Contract/f:valuedItem/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:Contract/f:valuedItem/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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: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: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: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:party">
|
||||
<sch:rule context="//f:Contract/f:signer/f:party">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:period">
|
||||
<sch:rule context="//f:Contract/f:term/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Contract/f:term/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:Contract/f:term/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Contract/f:term/f:applies">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Contract/f:term/f:subject">
|
||||
<sch:rule context="//f:Contract/f:term/f:subject">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:entity">
|
||||
<sch:rule context="//f:Contract/f:term/f:actor/f:entity">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:entityReference">
|
||||
<sch:rule context="//f:Contract/f:term/f:valuedItem/f:entityReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:period">
|
||||
<sch:rule context="//f:Contract/f:term/f:valuedItem/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Contract/f:term/f:valuedItem/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:Contract/f:term/f:valuedItem/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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: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: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: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: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:rule context="//f:Contract/f:bindingReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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: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:rule context="//f:Contract/f:friendly/f:contentReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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: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:rule context="//f:Contract/f:legal/f:contentReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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: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:rule context="//f:Contract/f:rule/f:contentReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,42 +10,42 @@
|
|||
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>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">
|
||||
<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:rule context="//f:Contraindication/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Contraindication/f:patient">
|
||||
<sch:rule context="//f:Contraindication/f:patient">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:implicated">
|
||||
<sch:rule context="//f:Contraindication/f:implicated">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Contraindication/f:author">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:period">
|
||||
<sch:rule context="//f:Contraindication/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Contraindication/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:Contraindication/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:author">
|
||||
<sch:rule context="//f:Contraindication/f:mitigation/f:author">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,60 +10,60 @@
|
|||
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>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">
|
||||
<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:rule context="//f:Coverage/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Coverage/f:issuer">
|
||||
<sch:rule context="//f:Coverage/f:issuer">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:period">
|
||||
<sch:rule context="//f:Coverage/f:bin/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Coverage/f:bin/f:assigner">
|
||||
<sch:rule context="//f:Coverage/f:bin/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Coverage/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Coverage/f:subscriberId/f:period">
|
||||
<sch:rule context="//f:Coverage/f:subscriberId/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Coverage/f:subscriberId/f:assigner">
|
||||
<sch:rule context="//f:Coverage/f:subscriberId/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:period">
|
||||
<sch:rule context="//f:Coverage/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Coverage/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:Coverage/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Coverage/f:subscriber">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:period">
|
||||
<sch:rule context="//f:Coverage/f:network/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Coverage/f:network/f:assigner">
|
||||
<sch:rule context="//f:Coverage/f:network/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Coverage/f:contract">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,43 +10,41 @@
|
|||
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>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">
|
||||
<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:rule context="//f:DataElement/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:DataElement/f:identifier/f:period">
|
||||
<sch:rule context="//f:DataElement/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:DataElement/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:DataElement/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:contact/f:telecom">
|
||||
<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:rule context="//f:DataElement/f:contact/f:telecom/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:DataElement/f:element">
|
||||
<sch:rule context="//f:DataElement/f:element">
|
||||
<sch:assert test="not(exists(f:base))">dae-1: No base allowed</sch:assert>
|
||||
<sch:assert test="not(exists(f:slicing))">dae-2: No slicing allowed</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:DataElement/f:element">
|
||||
<sch:assert test="(not(f:max/@value) and not(f:min/@value)) or (f:max/@value = '*') or (f:max/@value >= f:min/@value)">eld-2: Min <= Max</sch:assert>
|
||||
<sch:assert test="not(exists(f:min)) or not(exists(f:max)) or (not(f:max/@value) and not(f:min/@value)) or (f:max/@value = '*') or (f:max/@value >= f:min/@value)">eld-2: Min <= Max</sch:assert>
|
||||
<sch:assert test="not(exists(f:nameReference) and exists(f:*[starts-with(local-name(.), 'value')]))">eld-5: Either a namereference or a fixed value (but not both) is permitted</sch:assert>
|
||||
<sch:assert test="not(exists(f:*[starts-with(local-name(.), 'pattern')])) or (count(f:type)=1 )">eld-7: Pattern may only be specified if there is one type</sch:assert>
|
||||
<sch:assert test="not(exists(f:*[starts-with(local-name(.), 'fixed')])) or (count(f:type)=1 )">eld-6: Fixed value may only be specified if there is one type</sch:assert>
|
||||
|
@ -56,24 +54,24 @@
|
|||
<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-15: default value and meaningWhenMissing are mutually exclusive</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:DataElement/f:element/f:slicing">
|
||||
<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:rule context="//f:DataElement/f:element/f:max">
|
||||
<sch:assert test="@value='*' or (normalize-space(@value)!='' and normalize-space(translate(@value, '0123456789',''))='')">eld-3: Max SHALL be a number or "*"</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:DataElement/f:element/f:type">
|
||||
<sch: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: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: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:rule context="//f:DataElement/f:element/f:binding/f:valueSetReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,48 +10,48 @@
|
|||
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>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">
|
||||
<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:rule context="//f:Device/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Device/f:identifier/f:period">
|
||||
<sch:rule context="//f:Device/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:Device/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:Device/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:note/f:authorReference">
|
||||
<sch:rule context="//f:Device/f:note/f:authorReference">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:owner">
|
||||
<sch:rule context="//f:Device/f:owner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Device/f:location">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:Device/f:patient">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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: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:rule context="//f:Device/f:contact/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
</sch:pattern>
|
||||
</sch:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,42 +10,42 @@
|
|||
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>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">
|
||||
<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:rule context="//f:DeviceComponent/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:DeviceComponent/f:identifier/f:period">
|
||||
<sch:rule context="//f:DeviceComponent/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:DeviceComponent/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:DeviceComponent/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:DeviceComponent/f:source">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:DeviceComponent/f:parent">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:productionSpecification/f:componentId/f:period">
|
||||
<sch:rule context="//f:DeviceComponent/f:productionSpecification/f:componentId/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:DeviceComponent/f:productionSpecification/f:componentId/f:assigner">
|
||||
<sch:rule context="//f:DeviceComponent/f:productionSpecification/f:componentId/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=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:pattern>
|
||||
</sch:schema>
|
||||
|
|
|
@ -10,65 +10,64 @@
|
|||
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>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">
|
||||
<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:rule context="//f:DeviceMetric/f:text/f:div">
|
||||
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, <a> elements (either name or href), images and internally contained style attributes</sch:assert>
|
||||
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:DeviceMetric/f:identifier/f:period">
|
||||
<sch:rule context="//f:DeviceMetric/f:identifier/f:period">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:DeviceMetric/f:identifier/f:assigner">
|
||||
<sch:rule context="//f:DeviceMetric/f:identifier/f:assigner">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:source">
|
||||
<sch:rule context="//f:DeviceMetric/f:source">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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:rule context="//f:DeviceMetric/f:parent">
|
||||
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::*[self::f:entry or self::f:parameter]/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/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: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:boundsDuration">
|
||||
<sch:rule context="//f:DeviceMetric/f:measurementPeriod/f:repeat/f:boundsDuration">
|
||||
<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:DeviceMetric/f:measurementPeriod/f:repeat/f:boundsRange">
|
||||
<sch:rule context="//f:DeviceMetric/f:measurementPeriod/f:repeat/f:boundsRange">
|
||||
<sch:assert test="not(exists(f:low/f:value/@value)) or not(exists(f:high/f:value/@value)) or (number(f:low/f:value/@value) <= number(f:high/f:value/@value))">rng-2: If present, low SHALL have a lower value than high</sch:assert>
|
||||
<sch:assert test="not(exists(f:low/f:comparator) or exists(f:high/f:comparator))">rng-3: Quantity values cannot have a comparator when used in a Range</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:DeviceMetric/f:measurementPeriod/f:repeat/f:boundsRange/f:low">
|
||||
<sch:rule context="//f:DeviceMetric/f:measurementPeriod/f:repeat/f:boundsRange/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:DeviceMetric/f:measurementPeriod/f:repeat/f:boundsRange/f:high">
|
||||
<sch:rule context="//f:DeviceMetric/f:measurementPeriod/f:repeat/f:boundsRange/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:DeviceMetric/f:measurementPeriod/f:repeat/f:boundsPeriod">
|
||||
<sch:rule context="//f:DeviceMetric/f:measurementPeriod/f:repeat/f:boundsPeriod">
|
||||
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value <= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:DeviceMetric/f:measurementPeriod/f:repeat/f:duration">
|
||||
<sch:rule context="//f:DeviceMetric/f:measurementPeriod/f:repeat/f:duration">
|
||||
<sch:assert test="@value >= 0 or not(@value)">tim-4: duration SHALL be a non-negative value</sch:assert>
|
||||
</sch:rule>
|
||||
<sch:rule context="f:DeviceMetric/f:measurementPeriod/f:repeat/f:period">
|
||||
<sch:rule context="//f:DeviceMetric/f:measurementPeriod/f:repeat/f:period">
|
||||
<sch:assert test="@value >= 0 or not(@value)">tim-5: period SHALL be a non-negative value</sch:assert>
|
||||
</sch:rule>
|
||||
</sch:pattern>
|
||||
</sch:pattern>
|
||||
</sch:schema>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue