Credit for #1065 and forward-port fix to R4 provider
This commit is contained in:
parent
f8b232bb67
commit
b3c9b32db4
|
@ -28,6 +28,7 @@ import org.hl7.fhir.r4.model.Enumerations.PublicationStatus;
|
||||||
import org.hl7.fhir.r4.model.OperationDefinition.OperationDefinitionParameterComponent;
|
import org.hl7.fhir.r4.model.OperationDefinition.OperationDefinitionParameterComponent;
|
||||||
import org.hl7.fhir.r4.model.OperationDefinition.OperationKind;
|
import org.hl7.fhir.r4.model.OperationDefinition.OperationKind;
|
||||||
import org.hl7.fhir.r4.model.OperationDefinition.OperationParameterUse;
|
import org.hl7.fhir.r4.model.OperationDefinition.OperationParameterUse;
|
||||||
|
import org.hl7.fhir.r4.model.codesystems.UnknownContentCode;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -71,13 +72,15 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerCapabilityStatementProvider.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerCapabilityStatementProvider.class);
|
||||||
private boolean myCache = true;
|
private boolean myCache = true;
|
||||||
private volatile CapabilityStatement myCapabilityStatement;
|
private volatile CapabilityStatement myCapabilityStatement;
|
||||||
|
private IdentityHashMap<SearchMethodBinding, String> myNamedSearchMethodBindingToName;
|
||||||
|
private HashMap<String, List<SearchMethodBinding>> mySearchNameToBindings;
|
||||||
private IdentityHashMap<OperationMethodBinding, String> myOperationBindingToName;
|
private IdentityHashMap<OperationMethodBinding, String> myOperationBindingToName;
|
||||||
private HashMap<String, List<OperationMethodBinding>> myOperationNameToBindings;
|
private HashMap<String, List<OperationMethodBinding>> myOperationNameToBindings;
|
||||||
private String myPublisher = "Not provided";
|
private String myPublisher = "Not provided";
|
||||||
private Callable<RestulfulServerConfiguration> myServerConfiguration;
|
private Callable<RestulfulServerConfiguration> myServerConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No-arg constructor and seetter so that the ServerConfirmanceProvider can be Spring-wired with the RestfulService avoiding the potential reference cycle that would happen.
|
* No-arg constructor and setter so that the ServerConformanceProvider can be Spring-wired with the RestfulService avoiding the potential reference cycle that would happen.
|
||||||
*/
|
*/
|
||||||
public ServerCapabilityStatementProvider() {
|
public ServerCapabilityStatementProvider() {
|
||||||
super();
|
super();
|
||||||
|
@ -119,12 +122,12 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, List<BaseMethodBinding<?>>> collectMethodBindings() {
|
private Map<String, List<BaseMethodBinding<?>>> collectMethodBindings() {
|
||||||
Map<String, List<BaseMethodBinding<?>>> resourceToMethods = new TreeMap<>();
|
Map<String, List<BaseMethodBinding<?>>> resourceToMethods = new TreeMap<String, List<BaseMethodBinding<?>>>();
|
||||||
for (ResourceBinding next : getServerConfiguration().getResourceBindings()) {
|
for (ResourceBinding next : getServerConfiguration().getResourceBindings()) {
|
||||||
String resourceName = next.getResourceName();
|
String resourceName = next.getResourceName();
|
||||||
for (BaseMethodBinding<?> nextMethodBinding : next.getMethodBindings()) {
|
for (BaseMethodBinding<?> nextMethodBinding : next.getMethodBindings()) {
|
||||||
if (resourceToMethods.containsKey(resourceName) == false) {
|
if (resourceToMethods.containsKey(resourceName) == false) {
|
||||||
resourceToMethods.put(resourceName, new ArrayList<>());
|
resourceToMethods.put(resourceName, new ArrayList<BaseMethodBinding<?>>());
|
||||||
}
|
}
|
||||||
resourceToMethods.get(resourceName).add(nextMethodBinding);
|
resourceToMethods.get(resourceName).add(nextMethodBinding);
|
||||||
}
|
}
|
||||||
|
@ -151,6 +154,17 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
|
||||||
return DateTimeType.now();
|
return DateTimeType.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String createNamedQueryName(SearchMethodBinding searchMethodBinding) {
|
||||||
|
StringBuilder retVal = new StringBuilder();
|
||||||
|
if (searchMethodBinding.getResourceName() != null) {
|
||||||
|
retVal.append(searchMethodBinding.getResourceName());
|
||||||
|
}
|
||||||
|
retVal.append("-query-");
|
||||||
|
retVal.append(searchMethodBinding.getQueryName());
|
||||||
|
|
||||||
|
return retVal.toString();
|
||||||
|
}
|
||||||
|
|
||||||
private String createOperationName(OperationMethodBinding theMethodBinding) {
|
private String createOperationName(OperationMethodBinding theMethodBinding) {
|
||||||
StringBuilder retVal = new StringBuilder();
|
StringBuilder retVal = new StringBuilder();
|
||||||
if (theMethodBinding.getResourceName() != null) {
|
if (theMethodBinding.getResourceName() != null) {
|
||||||
|
@ -230,14 +244,15 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
|
||||||
Set<String> operationNames = new HashSet<>();
|
Set<String> operationNames = new HashSet<>();
|
||||||
|
|
||||||
Map<String, List<BaseMethodBinding<?>>> resourceToMethods = collectMethodBindings();
|
Map<String, List<BaseMethodBinding<?>>> resourceToMethods = collectMethodBindings();
|
||||||
for (Entry<String, List<BaseMethodBinding<?>>> nextEntry : resourceToMethods.entrySet())
|
for (Entry<String, List<BaseMethodBinding<?>>> nextEntry : resourceToMethods.entrySet()) {
|
||||||
|
|
||||||
if (nextEntry.getKey().isEmpty() == false) {
|
if (nextEntry.getKey().isEmpty() == false) {
|
||||||
Set<TypeRestfulInteraction> resourceOps = new HashSet<TypeRestfulInteraction>();
|
Set<TypeRestfulInteraction> resourceOps = new HashSet<>();
|
||||||
CapabilityStatementRestResourceComponent resource = rest.addResource();
|
CapabilityStatementRestResourceComponent resource = rest.addResource();
|
||||||
String resourceName = nextEntry.getKey();
|
String resourceName = nextEntry.getKey();
|
||||||
RuntimeResourceDefinition def = getServerConfiguration().getFhirContext().getResourceDefinition(resourceName);
|
RuntimeResourceDefinition def = getServerConfiguration().getFhirContext().getResourceDefinition(resourceName);
|
||||||
resource.getTypeElement().setValue(def.getName());
|
resource.getTypeElement().setValue(def.getName());
|
||||||
resource.getProfileElement().setValue(def.getResourceProfile(serverBase));
|
resource.getProfileElement().setValue((def.getResourceProfile(serverBase)));
|
||||||
|
|
||||||
TreeSet<String> includes = new TreeSet<>();
|
TreeSet<String> includes = new TreeSet<>();
|
||||||
|
|
||||||
|
@ -293,13 +308,21 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
|
||||||
checkBindingForSystemOps(rest, systemOps, nextMethodBinding);
|
checkBindingForSystemOps(rest, systemOps, nextMethodBinding);
|
||||||
|
|
||||||
if (nextMethodBinding instanceof SearchMethodBinding) {
|
if (nextMethodBinding instanceof SearchMethodBinding) {
|
||||||
handleSearchMethodBinding(rest, resource, resourceName, def, includes, (SearchMethodBinding) nextMethodBinding);
|
SearchMethodBinding methodBinding = (SearchMethodBinding) nextMethodBinding;
|
||||||
|
if (methodBinding.getQueryName() != null) {
|
||||||
|
String queryName = myNamedSearchMethodBindingToName.get(methodBinding);
|
||||||
|
if (operationNames.add(queryName)) {
|
||||||
|
rest.addOperation().setName(methodBinding.getQueryName()).setDefinition(("OperationDefinition/" + queryName));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
handleNamelessSearchMethodBinding(rest, resource, resourceName, def, includes, (SearchMethodBinding) nextMethodBinding);
|
||||||
|
}
|
||||||
} else if (nextMethodBinding instanceof OperationMethodBinding) {
|
} else if (nextMethodBinding instanceof OperationMethodBinding) {
|
||||||
OperationMethodBinding methodBinding = (OperationMethodBinding) nextMethodBinding;
|
OperationMethodBinding methodBinding = (OperationMethodBinding) nextMethodBinding;
|
||||||
String opName = myOperationBindingToName.get(methodBinding);
|
String opName = myOperationBindingToName.get(methodBinding);
|
||||||
if (operationNames.add(opName)) {
|
if (operationNames.add(opName)) {
|
||||||
// Only add each operation (by name) once
|
// Only add each operation (by name) once
|
||||||
rest.addOperation().setName(methodBinding.getName().substring(1)).setDefinition("OperationDefinition/" + opName);
|
rest.addOperation().setName(methodBinding.getName().substring(1)).setDefinition(("OperationDefinition/" + opName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,19 +357,19 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
|
||||||
String opName = myOperationBindingToName.get(methodBinding);
|
String opName = myOperationBindingToName.get(methodBinding);
|
||||||
if (operationNames.add(opName)) {
|
if (operationNames.add(opName)) {
|
||||||
ourLog.debug("Found bound operation: {}", opName);
|
ourLog.debug("Found bound operation: {}", opName);
|
||||||
rest.addOperation().setName(methodBinding.getName().substring(1)).setDefinition("OperationDefinition/" + opName);
|
rest.addOperation().setName(methodBinding.getName().substring(1)).setDefinition(("OperationDefinition/" + opName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
myCapabilityStatement = retVal;
|
myCapabilityStatement = retVal;
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleNamelessSearchMethodBinding(CapabilityStatementRestComponent rest, CapabilityStatementRestResourceComponent resource, String resourceName, RuntimeResourceDefinition def, TreeSet<String> includes,
|
||||||
private void handleSearchMethodBinding(CapabilityStatementRestComponent rest, CapabilityStatementRestResourceComponent resource, String resourceName, RuntimeResourceDefinition def, TreeSet<String> includes,
|
SearchMethodBinding searchMethodBinding) {
|
||||||
SearchMethodBinding searchMethodBinding) {
|
|
||||||
includes.addAll(searchMethodBinding.getIncludes());
|
includes.addAll(searchMethodBinding.getIncludes());
|
||||||
|
|
||||||
List<IParameter> params = searchMethodBinding.getParameters();
|
List<IParameter> params = searchMethodBinding.getParameters();
|
||||||
|
@ -434,6 +457,8 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
|
||||||
|
|
||||||
@Initialize
|
@Initialize
|
||||||
public void initializeOperations() {
|
public void initializeOperations() {
|
||||||
|
myNamedSearchMethodBindingToName = new IdentityHashMap<>();
|
||||||
|
mySearchNameToBindings = new HashMap<>();
|
||||||
myOperationBindingToName = new IdentityHashMap<>();
|
myOperationBindingToName = new IdentityHashMap<>();
|
||||||
myOperationNameToBindings = new HashMap<>();
|
myOperationNameToBindings = new HashMap<>();
|
||||||
|
|
||||||
|
@ -452,9 +477,23 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
|
||||||
|
|
||||||
myOperationBindingToName.put(methodBinding, name);
|
myOperationBindingToName.put(methodBinding, name);
|
||||||
if (myOperationNameToBindings.containsKey(name) == false) {
|
if (myOperationNameToBindings.containsKey(name) == false) {
|
||||||
myOperationNameToBindings.put(name, new ArrayList<OperationMethodBinding>());
|
myOperationNameToBindings.put(name, new ArrayList<>());
|
||||||
}
|
}
|
||||||
myOperationNameToBindings.get(name).add(methodBinding);
|
myOperationNameToBindings.get(name).add(methodBinding);
|
||||||
|
} else if (nextMethodBinding instanceof SearchMethodBinding) {
|
||||||
|
SearchMethodBinding methodBinding = (SearchMethodBinding) nextMethodBinding;
|
||||||
|
if (myNamedSearchMethodBindingToName.containsKey(methodBinding)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String name = createNamedQueryName(methodBinding);
|
||||||
|
ourLog.debug("Detected named query: {}", name);
|
||||||
|
|
||||||
|
myNamedSearchMethodBindingToName.put(methodBinding, name);
|
||||||
|
if (!mySearchNameToBindings.containsKey(name)) {
|
||||||
|
mySearchNameToBindings.put(name, new ArrayList<>());
|
||||||
|
}
|
||||||
|
mySearchNameToBindings.get(name).add(methodBinding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -465,11 +504,69 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
|
||||||
if (theId == null || theId.hasIdPart() == false) {
|
if (theId == null || theId.hasIdPart() == false) {
|
||||||
throw new ResourceNotFoundException(theId);
|
throw new ResourceNotFoundException(theId);
|
||||||
}
|
}
|
||||||
List<OperationMethodBinding> sharedDescriptions = myOperationNameToBindings.get(theId.getIdPart());
|
List<OperationMethodBinding> operationBindings = myOperationNameToBindings.get(theId.getIdPart());
|
||||||
if (sharedDescriptions == null || sharedDescriptions.isEmpty()) {
|
if (operationBindings != null && !operationBindings.isEmpty()) {
|
||||||
throw new ResourceNotFoundException(theId);
|
return readOperationDefinitionForOperation(operationBindings);
|
||||||
|
}
|
||||||
|
List<SearchMethodBinding> searchBindings = mySearchNameToBindings.get(theId.getIdPart());
|
||||||
|
if (searchBindings != null && !searchBindings.isEmpty()) {
|
||||||
|
return readOperationDefinitionForNamedSearch(searchBindings);
|
||||||
|
}
|
||||||
|
throw new ResourceNotFoundException(theId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private OperationDefinition readOperationDefinitionForNamedSearch(List<SearchMethodBinding> bindings) {
|
||||||
|
OperationDefinition op = new OperationDefinition();
|
||||||
|
op.setStatus(PublicationStatus.ACTIVE);
|
||||||
|
op.setKind(OperationKind.QUERY);
|
||||||
|
op.setAffectsState(false);
|
||||||
|
|
||||||
|
op.setSystem(false);
|
||||||
|
op.setType(false);
|
||||||
|
op.setInstance(false);
|
||||||
|
|
||||||
|
Set<String> inParams = new HashSet<>();
|
||||||
|
|
||||||
|
for (SearchMethodBinding binding : bindings) {
|
||||||
|
if (isNotBlank(binding.getDescription())) {
|
||||||
|
op.setDescription(binding.getDescription());
|
||||||
|
}
|
||||||
|
if (isBlank(binding.getResourceProviderResourceName())) {
|
||||||
|
op.setSystem(true);
|
||||||
|
} else {
|
||||||
|
op.setType(true);
|
||||||
|
op.addResourceElement().setValue(binding.getResourceProviderResourceName());
|
||||||
|
}
|
||||||
|
op.setCode(binding.getQueryName());
|
||||||
|
for (IParameter nextParamUntyped : binding.getParameters()) {
|
||||||
|
if (nextParamUntyped instanceof SearchParameter) {
|
||||||
|
SearchParameter nextParam = (SearchParameter) nextParamUntyped;
|
||||||
|
if (!inParams.add(nextParam.getName())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
OperationDefinitionParameterComponent param = op.addParameter();
|
||||||
|
param.setUse(OperationParameterUse.IN);
|
||||||
|
param.setType("string");
|
||||||
|
param.getSearchTypeElement().setValueAsString(nextParam.getParamType().getCode());
|
||||||
|
param.setMin(nextParam.isRequired() ? 1 : 0);
|
||||||
|
param.setMax("1");
|
||||||
|
param.setName(nextParam.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBlank(op.getName())) {
|
||||||
|
if (isNotBlank(op.getDescription())) {
|
||||||
|
op.setName(op.getDescription());
|
||||||
|
} else {
|
||||||
|
op.setName(op.getCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OperationDefinition readOperationDefinitionForOperation(List<OperationMethodBinding> bindings) {
|
||||||
OperationDefinition op = new OperationDefinition();
|
OperationDefinition op = new OperationDefinition();
|
||||||
op.setStatus(PublicationStatus.ACTIVE);
|
op.setStatus(PublicationStatus.ACTIVE);
|
||||||
op.setKind(OperationKind.OPERATION);
|
op.setKind(OperationKind.OPERATION);
|
||||||
|
@ -480,10 +577,10 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
|
||||||
op.setType(false);
|
op.setType(false);
|
||||||
op.setInstance(false);
|
op.setInstance(false);
|
||||||
|
|
||||||
Set<String> inParams = new HashSet<String>();
|
Set<String> inParams = new HashSet<>();
|
||||||
Set<String> outParams = new HashSet<String>();
|
Set<String> outParams = new HashSet<>();
|
||||||
|
|
||||||
for (OperationMethodBinding sharedDescription : sharedDescriptions) {
|
for (OperationMethodBinding sharedDescription : bindings) {
|
||||||
if (isNotBlank(sharedDescription.getDescription())) {
|
if (isNotBlank(sharedDescription.getDescription())) {
|
||||||
op.setDescription(sharedDescription.getDescription());
|
op.setDescription(sharedDescription.getDescription());
|
||||||
}
|
}
|
||||||
|
@ -569,8 +666,9 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
|
||||||
* See the class documentation for an important note if you are extending this class
|
* See the class documentation for an important note if you are extending this class
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public void setCache(boolean theCache) {
|
public ServerCapabilityStatementProvider setCache(boolean theCache) {
|
||||||
myCache = theCache;
|
myCache = theCache;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -15,8 +15,6 @@ import org.hl7.fhir.r4.utils.FHIRPathEngine.ExpressionNodeWithOffset;
|
||||||
import org.hl7.fhir.r4.utils.FHIRPathEngine.IEvaluationContext;
|
import org.hl7.fhir.r4.utils.FHIRPathEngine.IEvaluationContext;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
|
||||||
import javafx.scene.Parent;
|
|
||||||
|
|
||||||
public class LiquidEngine implements IEvaluationContext {
|
public class LiquidEngine implements IEvaluationContext {
|
||||||
|
|
||||||
public interface ILiquidEngineIcludeResolver {
|
public interface ILiquidEngineIcludeResolver {
|
||||||
|
|
|
@ -0,0 +1,183 @@
|
||||||
|
|
||||||
|
package ca.uhn.fhir.rest.server;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.model.api.Include;
|
||||||
|
import ca.uhn.fhir.model.api.annotation.Description;
|
||||||
|
import ca.uhn.fhir.rest.annotation.*;
|
||||||
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.api.SortSpec;
|
||||||
|
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||||
|
import ca.uhn.fhir.rest.param.*;
|
||||||
|
import org.hl7.fhir.r4.model.Organization;
|
||||||
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
import org.hl7.fhir.r4.model.Practitioner;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
// import ca.uhn.fhir.model.dstu.resource.Binary;
|
||||||
|
// import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||||
|
// import ca.uhn.fhir.model.api.Bundle;
|
||||||
|
|
||||||
|
|
||||||
|
public class PatientResourceProvider implements IResourceProvider
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Patient> getResourceType() {
|
||||||
|
return Patient.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Search()
|
||||||
|
public IBundleProvider search(
|
||||||
|
javax.servlet.http.HttpServletRequest theServletRequest,
|
||||||
|
|
||||||
|
@Description(shortDefinition="The resource identity")
|
||||||
|
@OptionalParam(name="_id")
|
||||||
|
StringAndListParam theId,
|
||||||
|
|
||||||
|
@Description(shortDefinition="The resource language")
|
||||||
|
@OptionalParam(name="_language")
|
||||||
|
StringAndListParam theResourceLanguage,
|
||||||
|
|
||||||
|
@Description(shortDefinition="Search the contents of the resource's data using a fulltext search")
|
||||||
|
@OptionalParam(name=Constants.PARAM_CONTENT)
|
||||||
|
StringAndListParam theFtContent,
|
||||||
|
|
||||||
|
@Description(shortDefinition="Search the contents of the resource's narrative using a fulltext search")
|
||||||
|
@OptionalParam(name=Constants.PARAM_TEXT)
|
||||||
|
StringAndListParam theFtText,
|
||||||
|
|
||||||
|
@Description(shortDefinition="Search for resources which have the given tag")
|
||||||
|
@OptionalParam(name=Constants.PARAM_TAG)
|
||||||
|
TokenAndListParam theSearchForTag,
|
||||||
|
|
||||||
|
@Description(shortDefinition="Search for resources which have the given security labels")
|
||||||
|
@OptionalParam(name=Constants.PARAM_SECURITY)
|
||||||
|
TokenAndListParam theSearchForSecurity,
|
||||||
|
|
||||||
|
@Description(shortDefinition="Search for resources which have the given profile")
|
||||||
|
@OptionalParam(name=Constants.PARAM_PROFILE)
|
||||||
|
UriAndListParam theSearchForProfile,
|
||||||
|
|
||||||
|
|
||||||
|
@Description(shortDefinition="A patient identifier")
|
||||||
|
@OptionalParam(name="identifier")
|
||||||
|
TokenAndListParam theIdentifier,
|
||||||
|
|
||||||
|
@Description(shortDefinition="A portion of either family or given name of the patient")
|
||||||
|
@OptionalParam(name="name")
|
||||||
|
StringAndListParam theName,
|
||||||
|
|
||||||
|
@Description(shortDefinition="A portion of the family name of the patient")
|
||||||
|
@OptionalParam(name="family")
|
||||||
|
StringAndListParam theFamily,
|
||||||
|
|
||||||
|
@Description(shortDefinition="A portion of the given name of the patient")
|
||||||
|
@OptionalParam(name="given")
|
||||||
|
StringAndListParam theGiven,
|
||||||
|
|
||||||
|
@Description(shortDefinition="A portion of either family or given name using some kind of phonetic matching algorithm")
|
||||||
|
@OptionalParam(name="phonetic")
|
||||||
|
StringAndListParam thePhonetic,
|
||||||
|
|
||||||
|
@Description(shortDefinition="The value in any kind of telecom details of the patient")
|
||||||
|
@OptionalParam(name="telecom")
|
||||||
|
TokenAndListParam theTelecom,
|
||||||
|
|
||||||
|
@Description(shortDefinition="A value in a phone contact")
|
||||||
|
@OptionalParam(name="phone")
|
||||||
|
TokenAndListParam thePhone,
|
||||||
|
|
||||||
|
@Description(shortDefinition="A value in an email contact")
|
||||||
|
@OptionalParam(name="email")
|
||||||
|
TokenAndListParam theEmail,
|
||||||
|
|
||||||
|
@Description(shortDefinition="An address in any kind of address/part of the patient")
|
||||||
|
@OptionalParam(name="address")
|
||||||
|
StringAndListParam theAddress,
|
||||||
|
|
||||||
|
@Description(shortDefinition="A city specified in an address")
|
||||||
|
@OptionalParam(name="address-city")
|
||||||
|
StringAndListParam theAddress_city,
|
||||||
|
|
||||||
|
@Description(shortDefinition="A state specified in an address")
|
||||||
|
@OptionalParam(name="address-state")
|
||||||
|
StringAndListParam theAddress_state,
|
||||||
|
|
||||||
|
@Description(shortDefinition="A postalCode specified in an address")
|
||||||
|
@OptionalParam(name="address-postalcode")
|
||||||
|
StringAndListParam theAddress_postalcode,
|
||||||
|
|
||||||
|
@Description(shortDefinition="A country specified in an address")
|
||||||
|
@OptionalParam(name="address-country")
|
||||||
|
StringAndListParam theAddress_country,
|
||||||
|
|
||||||
|
@Description(shortDefinition="A use code specified in an address")
|
||||||
|
@OptionalParam(name="address-use")
|
||||||
|
TokenAndListParam theAddress_use,
|
||||||
|
|
||||||
|
@Description(shortDefinition="Gender of the patient")
|
||||||
|
@OptionalParam(name="gender")
|
||||||
|
TokenAndListParam theGender,
|
||||||
|
|
||||||
|
@Description(shortDefinition="Language code (irrespective of use value)")
|
||||||
|
@OptionalParam(name="language")
|
||||||
|
TokenAndListParam theLanguage,
|
||||||
|
|
||||||
|
@Description(shortDefinition="The patient's date of birth")
|
||||||
|
@OptionalParam(name="birthdate")
|
||||||
|
DateRangeParam theBirthdate,
|
||||||
|
|
||||||
|
@Description(shortDefinition="The organization at which this person is a patient")
|
||||||
|
@OptionalParam(name="organization", targetTypes={ Organization.class } )
|
||||||
|
ReferenceAndListParam theOrganization,
|
||||||
|
|
||||||
|
@Description(shortDefinition="Patient's nominated care provider, could be a care manager, not the organization that manages the record")
|
||||||
|
@OptionalParam(name="careprovider", targetTypes={ Organization.class , Practitioner.class } )
|
||||||
|
ReferenceAndListParam theCareprovider,
|
||||||
|
|
||||||
|
@Description(shortDefinition="Whether the patient record is active")
|
||||||
|
@OptionalParam(name="active")
|
||||||
|
TokenAndListParam theActive,
|
||||||
|
|
||||||
|
@Description(shortDefinition="The species for animal patients")
|
||||||
|
@OptionalParam(name="animal-species")
|
||||||
|
TokenAndListParam theAnimal_species,
|
||||||
|
|
||||||
|
@Description(shortDefinition="The breed for animal patients")
|
||||||
|
@OptionalParam(name="animal-breed")
|
||||||
|
TokenAndListParam theAnimal_breed,
|
||||||
|
|
||||||
|
@Description(shortDefinition="All patients linked to the given patient")
|
||||||
|
@OptionalParam(name="link", targetTypes={ Patient.class } )
|
||||||
|
ReferenceAndListParam theLink,
|
||||||
|
|
||||||
|
@Description(shortDefinition="This patient has been marked as deceased, or as a death date entered")
|
||||||
|
@OptionalParam(name="deceased")
|
||||||
|
TokenAndListParam theDeceased,
|
||||||
|
|
||||||
|
@Description(shortDefinition="The date of death has been provided and satisfies this search value")
|
||||||
|
@OptionalParam(name="deathdate")
|
||||||
|
DateRangeParam theDeathdate,
|
||||||
|
|
||||||
|
@IncludeParam(reverse=true)
|
||||||
|
Set<Include> theRevIncludes,
|
||||||
|
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||||
|
@OptionalParam(name="_lastUpdated")
|
||||||
|
DateRangeParam theLastUpdated,
|
||||||
|
|
||||||
|
@IncludeParam(allow= {
|
||||||
|
"Patient:careprovider" , "Patient:link" , "Patient:organization" , "Patient:careprovider" , "Patient:link" , "Patient:organization" , "Patient:careprovider" , "Patient:link" , "Patient:organization" , "*"
|
||||||
|
})
|
||||||
|
Set<Include> theIncludes,
|
||||||
|
|
||||||
|
@Sort
|
||||||
|
SortSpec theSort,
|
||||||
|
|
||||||
|
@Count
|
||||||
|
Integer theCount
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,90 +1,90 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
|
||||||
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
|
||||||
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
|
||||||
<!--
|
<!--
|
||||||
This file contains just the constraints for the resource CapabilityStatement
|
This file contains just the constraints for the resource CapabilityStatement
|
||||||
It is provided for documentation purposes. When actually validating,
|
It is provided for documentation purposes. When actually validating,
|
||||||
always use fhir-invariants.sch (because of the way containment works)
|
always use fhir-invariants.sch (because of the way containment works)
|
||||||
Alternatively you can use this file to build a smaller version of
|
Alternatively you can use this file to build a smaller version of
|
||||||
fhir-invariants.sch (the contents are identical; only include those
|
fhir-invariants.sch (the contents are identical; only include those
|
||||||
resources relevant to your implementation).
|
resources relevant to your implementation).
|
||||||
-->
|
-->
|
||||||
<sch:pattern>
|
<sch:pattern>
|
||||||
<sch:title>Global</sch:title>
|
<sch:title>Global</sch:title>
|
||||||
<sch:rule context="f:extension">
|
<sch:rule context="f:extension">
|
||||||
<sch:assert test="exists(f:extension)!=exists(f:*[starts-with(local-name(.), 'value')])">ext-1: Must have either extensions or value[x], not both</sch:assert>
|
<sch:assert test="exists(f:extension)!=exists(f:*[starts-with(local-name(.), 'value')])">ext-1: Must have either extensions or value[x], not both</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
<sch:rule context="f:modifierExtension">
|
<sch:rule context="f:modifierExtension">
|
||||||
<sch:assert test="exists(f:extension)!=exists(f:*[starts-with(local-name(.), 'value')])">ext-1: Must have either extensions or value[x], not both</sch:assert>
|
<sch:assert test="exists(f:extension)!=exists(f:*[starts-with(local-name(.), 'value')])">ext-1: Must have either extensions or value[x], not both</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
</sch:pattern>
|
</sch:pattern>
|
||||||
<sch:pattern>
|
<sch:pattern>
|
||||||
<sch:title>Global 1</sch:title>
|
<sch:title>Global 1</sch:title>
|
||||||
<sch:rule context="f:*">
|
<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:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
</sch:pattern>
|
</sch:pattern>
|
||||||
<sch:pattern>
|
<sch:pattern>
|
||||||
<sch:title>CapabilityStatement</sch:title>
|
<sch:title>CapabilityStatement</sch:title>
|
||||||
<sch:rule context="f:CapabilityStatement">
|
<sch:rule context="f:CapabilityStatement">
|
||||||
<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:contained)">dom-2: If the resource is contained in another resource, it SHALL NOT contain nested Resources</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(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 $contained in f:contained return $contained[not(parent::*/descendant::f:reference/@value=concat('#', $contained/*/id/@value) or descendant::f:reference[@value='#'])]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource or SHALL refer to the containing resource</sch:assert>
|
<sch:assert test="not(exists(for $contained in f:contained return $contained[not(parent::*/descendant::f:reference/@value=concat('#', $contained/*/id/@value) or descendant::f:reference[@value='#'])]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource or SHALL refer to the containing resource</sch:assert>
|
||||||
<sch:assert test="not(exists(f:contained/*/f:meta/f:security))">dom-5: If a resource is contained in another resource, it SHALL NOT have a security label</sch:assert>
|
<sch:assert test="not(exists(f:contained/*/f:meta/f:security))">dom-5: If a resource is contained in another resource, it SHALL NOT have a security label</sch:assert>
|
||||||
<sch:assert test="count(f:document[f:mode/@value='producer'])=count(distinct-values(f:document[f:mode/@value='producer']/f:profile/f:reference/@value)) and count(f:document[f:mode/@value='consumer'])=count(distinct-values(f:document[f:mode/@value='consumer']/f:profile/f:reference/@value))">cpb-7: The set of documents must be unique by the combination of profile and mode.</sch:assert>
|
<sch:assert test="count(f:document[f:mode/@value='producer'])=count(distinct-values(f:document[f:mode/@value='producer']/f:profile/f:reference/@value)) and count(f:document[f:mode/@value='consumer'])=count(distinct-values(f:document[f:mode/@value='consumer']/f:profile/f:reference/@value))">cpb-7: The set of documents must be unique by the combination of profile and mode.</sch:assert>
|
||||||
<sch:assert test="not(f:kind/@value='instance') or (not(exists(f:implementation)) and not(exists(f:software)))">cpb-16: If kind = requirements, implementation and software must be absent</sch:assert>
|
<sch:assert test="not(f:kind/@value='requirements') or (not(exists(f:implementation)) and not(exists(f:software)))">cpb-16: If kind = requirements, implementation and software must be absent</sch:assert>
|
||||||
<sch:assert test=" not(f:kind/@value='instance') or (not(exists(f:implementation)) and exists(f:software))">cpb-15: If kind = capability, implementation must be absent, software must be present</sch:assert>
|
<sch:assert test=" not(f:kind/@value='capability') or (not(exists(f:implementation)) and exists(f:software))">cpb-15: If kind = capability, implementation must be absent, software must be present</sch:assert>
|
||||||
<sch:assert test="not(exists(f:messaging/f:endpoint)) or f:kind/@value = 'instance'">cpb-3: Messaging end-point is required (and is only permitted) when a statement is for an implementation.</sch:assert>
|
<sch:assert test="not(exists(f:messaging/f:endpoint)) or f:kind/@value = 'instance'">cpb-3: Messaging end-point is required (and is only permitted) when a statement is for an implementation.</sch:assert>
|
||||||
<sch:assert test="not(f:kind/@value='instance') or exists(f:implementation)">cpb-14: If kind = instance, implementation must be present and software may be present</sch:assert>
|
<sch:assert test="not(f:kind/@value='instance') or exists(f:implementation)">cpb-14: If kind = instance, implementation must be present and software may be present</sch:assert>
|
||||||
<sch:assert test="count(f:software | f:implementation | f:description) > 0">cpb-2: A Capability Statement SHALL have at least one of description, software, or implementation element.</sch:assert>
|
<sch:assert test="count(f:software | f:implementation | f:description) > 0">cpb-2: A Capability Statement SHALL have at least one of description, software, or implementation element.</sch:assert>
|
||||||
<sch:assert test="exists(f:rest) or exists(f:messaging) or exists(f:document)">cpb-1: A Capability Statement SHALL have at least one of REST, messaging or document element.</sch:assert>
|
<sch:assert test="exists(f:rest) or exists(f:messaging) or exists(f:document)">cpb-1: A Capability Statement SHALL have at least one of REST, messaging or document element.</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
<sch:rule context="f:CapabilityStatement/f:text/h:div">
|
<sch:rule context="f:CapabilityStatement/f:text/h:div">
|
||||||
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'col', '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', 'sub', 'sup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))]) and 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-1: The narrative SHALL contain only the basic html formatting elements and 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', 'col', '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', 'sub', 'sup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))]) and 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-1: The narrative SHALL contain only the basic html formatting elements and 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="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</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>
|
||||||
<sch:rule context="f:CapabilityStatement/f:contact/f:telecom">
|
<sch:rule context="f:CapabilityStatement/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: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>
|
||||||
<sch:rule context="f:CapabilityStatement/f:contact/f:telecom/f:period">
|
<sch:rule context="f:CapabilityStatement/f:contact/f:telecom/f:period">
|
||||||
<sch:assert test="not(exists(f:start/@value)) or not(exists(f:end/@value)) or (xs:dateTime(f:start/@value) <= xs:dateTime(f:end/@value))">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
<sch:assert test="not(exists(f:start/@value)) or not(exists(f:end/@value)) or (xs:dateTime(f:start/@value) <= xs:dateTime(f:end/@value))">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
<sch:rule context="f:CapabilityStatement/f:useContext/f:valueQuantity">
|
<sch:rule context="f:CapabilityStatement/f:useContext/f:valueQuantity">
|
||||||
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the unit is present, the system SHALL also be present</sch:assert>
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the unit is present, the system SHALL also be present</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
<sch:rule context="f:CapabilityStatement/f:useContext/f:valueRange">
|
<sch:rule context="f:CapabilityStatement/f:useContext/f:valueRange">
|
||||||
<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: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:rule>
|
</sch:rule>
|
||||||
<sch:rule context="f:CapabilityStatement/f:useContext/f:valueRange/f:low">
|
<sch:rule context="f:CapabilityStatement/f:useContext/f:valueRange/f:low">
|
||||||
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the unit is present, the system SHALL also be present</sch:assert>
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the unit is present, the system SHALL also be present</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
<sch:rule context="f:CapabilityStatement/f:useContext/f:valueRange/f:high">
|
<sch:rule context="f:CapabilityStatement/f:useContext/f:valueRange/f:high">
|
||||||
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the unit is present, the system SHALL also be present</sch:assert>
|
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the unit is present, the system SHALL also be present</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
<sch:rule context="f:CapabilityStatement/f:useContext/f:valueReference">
|
<sch:rule context="f:CapabilityStatement/f:useContext/f:valueReference">
|
||||||
<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 contained resource if a local reference is provided</sch:assert>
|
<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 contained resource if a local reference is provided</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
<sch:rule context="f:CapabilityStatement/f:useContext/f:valueReference/f:identifier/f:period">
|
<sch:rule context="f:CapabilityStatement/f:useContext/f:valueReference/f:identifier/f:period">
|
||||||
<sch:assert test="not(exists(f:start/@value)) or not(exists(f:end/@value)) or (xs:dateTime(f:start/@value) <= xs:dateTime(f:end/@value))">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
<sch:assert test="not(exists(f:start/@value)) or not(exists(f:end/@value)) or (xs:dateTime(f:start/@value) <= xs:dateTime(f:end/@value))">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
<sch:rule context="f:CapabilityStatement/f:useContext/f:valueReference/f:identifier/f:assigner">
|
<sch:rule context="f:CapabilityStatement/f:useContext/f:valueReference/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 contained resource if a local reference is provided</sch:assert>
|
<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 contained resource if a local reference is provided</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
<sch:rule context="f:CapabilityStatement/f:implementation/f:custodian">
|
<sch:rule context="f:CapabilityStatement/f:implementation/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 contained resource if a local reference is provided</sch:assert>
|
<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 contained resource if a local reference is provided</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
<sch:rule context="f:CapabilityStatement/f:implementation/f:custodian/f:identifier/f:period">
|
<sch:rule context="f:CapabilityStatement/f:implementation/f:custodian/f:identifier/f:period">
|
||||||
<sch:assert test="not(exists(f:start/@value)) or not(exists(f:end/@value)) or (xs:dateTime(f:start/@value) <= xs:dateTime(f:end/@value))">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
<sch:assert test="not(exists(f:start/@value)) or not(exists(f:end/@value)) or (xs:dateTime(f:start/@value) <= xs:dateTime(f:end/@value))">per-1: If present, start SHALL have a lower value than end</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
<sch:rule context="f:CapabilityStatement/f:implementation/f:custodian/f:identifier//f:assigner">
|
<sch:rule context="f:CapabilityStatement/f:implementation/f:custodian/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 contained resource if a local reference is provided</sch:assert>
|
<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 contained resource if a local reference is provided</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
<sch:rule context="f:CapabilityStatement/f:rest">
|
<sch:rule context="f:CapabilityStatement/f:rest">
|
||||||
<sch:assert test="count(f:resource)=count(distinct-values(f:resource/f:type/@value))">cpb-9: A given resource can only be described once per RESTful mode.</sch:assert>
|
<sch:assert test="count(f:resource)=count(distinct-values(f:resource/f:type/@value))">cpb-9: A given resource can only be described once per RESTful mode.</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
<sch:rule context="f:CapabilityStatement/f:rest/f:resource">
|
<sch:rule context="f:CapabilityStatement/f:rest/f:resource">
|
||||||
<sch:assert test="count(f:searchParam)=count(distinct-values(f:searchParam/f:name/@value))">cpb-12: Search parameter names 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))">cpb-12: Search parameter names must be unique in the context of a resource.</sch:assert>
|
||||||
</sch:rule>
|
</sch:rule>
|
||||||
</sch:pattern>
|
</sch:pattern>
|
||||||
</sch:schema>
|
</sch:schema>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
4
pom.xml
4
pom.xml
|
@ -485,6 +485,10 @@
|
||||||
<developer>
|
<developer>
|
||||||
<id>Cory00</id>
|
<id>Cory00</id>
|
||||||
</developer>
|
</developer>
|
||||||
|
<developer>
|
||||||
|
<id>srdo</id>
|
||||||
|
<name>Stig Døssing</name>
|
||||||
|
</developer>
|
||||||
</developers>
|
</developers>
|
||||||
|
|
||||||
<licenses>
|
<licenses>
|
||||||
|
|
|
@ -251,6 +251,10 @@
|
||||||
AuthorizationInterceptor is now able to authorize DELETE operations performed via a
|
AuthorizationInterceptor is now able to authorize DELETE operations performed via a
|
||||||
transaction operation. Previously these were always denied.
|
transaction operation. Previously these were always denied.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="add" issue="1065">
|
||||||
|
OperationDefinitions are now created for named queries in server
|
||||||
|
module. Thanks to Stig Døssing for the pull request!
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.6.0" date="2018-11-12" description="Food">
|
<release version="3.6.0" date="2018-11-12" description="Food">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
Loading…
Reference in New Issue