Merge branch 'master' into ja_20200524_npm_rework
This commit is contained in:
commit
17411a3659
|
@ -0,0 +1 @@
|
|||
|
|
@ -1,16 +1,20 @@
|
|||
trigger:
|
||||
branches:
|
||||
include:
|
||||
- '*'
|
||||
- master
|
||||
- release
|
||||
|
||||
pr:
|
||||
- master
|
||||
- release
|
||||
|
||||
# Different users have different machine setups, we run the build three times, on ubuntu, osx, and windows
|
||||
strategy:
|
||||
matrix:
|
||||
linux:
|
||||
imageName: "ubuntu-16.04"
|
||||
# mac:
|
||||
# imageName: "macos-10.14"
|
||||
# windows:
|
||||
# imageName: "vs2017-win2016"
|
||||
mac:
|
||||
imageName: "macos-10.14"
|
||||
windows:
|
||||
imageName: "vs2017-win2016"
|
||||
maxParallel: 3
|
||||
|
||||
pool:
|
||||
|
@ -19,18 +23,47 @@ pool:
|
|||
variables:
|
||||
currentImage: $(imageName)
|
||||
codecov: $(CODECOV_TOKEN)
|
||||
VERSION:
|
||||
|
||||
steps:
|
||||
- bash: ls -la
|
||||
- bash: pwd
|
||||
# This task pulls the <version> value from the org.hl7.fhir.r5 project pom.xml file. All modules are released as
|
||||
# the same version, at the same time, as defined in the root level pom.xml.
|
||||
- task: PowerShell@2
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: |
|
||||
[xml]$pomXml = Get-Content .\pom.xml
|
||||
[xml]$pomXml = Get-Content -Path .\pom.xml
|
||||
# version
|
||||
Write-Host $pomXml.project.version
|
||||
$version=$pomXml.project.version
|
||||
Write-Host "##vso[task.setvariable variable=version]$version"
|
||||
|
||||
# Prints out the build version, for debugging purposes
|
||||
- bash: echo Pulled version from pom.xml => $(version)
|
||||
|
||||
# Azure pipelines cannot pass variables between pipelines, but it can pass files, so we
|
||||
# pass the build id (ex: 1.1.13-SNAPSHOT) as a string in a file.
|
||||
# This is used in the release pipeline, so we create it here.
|
||||
# This is only done for the release branch.
|
||||
- bash: |
|
||||
echo $(version)
|
||||
VERSION=$(version)
|
||||
echo "$VERSION" > $(System.DefaultWorkingDirectory)/VERSION
|
||||
condition: and(eq(variables.currentImage, 'ubuntu-16.04'), eq(variables['Build.SourceBranch'], 'refs/heads/release'))
|
||||
|
||||
# Copies the VERSION file containing the build id (ex: 1.1.13-SNAPSHOT) to the staging directory
|
||||
# This is done for release versions only.
|
||||
- task: CopyFiles@2
|
||||
condition: and(eq(variables.currentImage, 'ubuntu-16.04'), eq(variables['Build.SourceBranch'], 'refs/heads/release'))
|
||||
displayName: 'Copy Files to: $(build.artifactstagingdirectory)'
|
||||
inputs:
|
||||
SourceFolder: '$(System.Defaultworkingdirectory)'
|
||||
Contents: "$(System.DefaultWorkingDirectory)/VERSION"
|
||||
TargetFolder: '$(build.artifactstagingdirectory)'
|
||||
|
||||
# Runs 'mvn clean package'
|
||||
- task: Maven@3
|
||||
inputs:
|
||||
mavenPomFile: 'pom.xml'
|
||||
|
@ -41,22 +74,34 @@ steps:
|
|||
publishJUnitResults: true
|
||||
testResultsFiles: '**/surefire-reports/TEST-*.xml'
|
||||
goals: 'clean package'
|
||||
|
||||
- bash: echo Current version => $(version)
|
||||
displayName: 'version'
|
||||
|
||||
# Upload test results to codecov
|
||||
- script: bash <(curl https://codecov.io/bash) -t $(codecov)
|
||||
displayName: 'codecov'
|
||||
displayName: 'codecov Bash Uploader'
|
||||
|
||||
# Publishes the test results to build artifacts.
|
||||
- task: PublishCodeCoverageResults@1
|
||||
displayName: 'Publish JaCoCo test results '
|
||||
inputs:
|
||||
codeCoverageTool: 'JaCoCo'
|
||||
summaryFileLocation: '$(System.DefaultWorkingDirectory)/org.hl7.fhir.report/target/site/jacoco-aggregate/jacoco.xml'
|
||||
reportDirectory: '$(System.DefaultWorkingDirectory)/org.hl7.fhir.report/target/site/jacoco-aggregate/'
|
||||
|
||||
# Publishes the built Validator jar to build artifacts. Primarily for testing and debugging builds.
|
||||
- task: PublishPipelineArtifact@1
|
||||
condition: eq(variables.currentImage, 'ubuntu-16.04')
|
||||
displayName: 'Publish Validator jar'
|
||||
condition: and(eq(variables.currentImage, 'ubuntu-16.04'), eq(variables['Build.SourceBranch'], 'refs/heads/release'))
|
||||
inputs:
|
||||
targetPath: "$(System.DefaultWorkingDirectory)/org.hl7.fhir.validation/target/org.hl7.fhir.validation-$(version).jar"
|
||||
artifactName: Validator
|
||||
|
||||
# Publishes the files we've moved into the staging directory, so they can be accessed by the
|
||||
# release pipeline. You will notice that we only do this for the ubuntu build, as doing it
|
||||
# for each of the three release pipelines will cause conflicts.
|
||||
# This is done for release versions only.
|
||||
- task: PublishBuildArtifacts@1
|
||||
condition: and(eq(variables.currentImage, 'ubuntu-16.04'), eq(variables['Build.SourceBranch'], 'refs/heads/release'))
|
||||
displayName: 'Publish Build Artifacts'
|
||||
inputs:
|
||||
PathtoPublish: '$(build.artifactstagingdirectory)'
|
||||
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
# This pipeline produces a SNAPSHOT build for each of the sub modules in
|
||||
# the core library, and publishes them to ossrh.
|
||||
trigger:
|
||||
- master
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
dstu2:
|
||||
module: "org.hl7.fhir.dstu2"
|
||||
dstu3:
|
||||
module: "org.hl7.fhir.dstu3"
|
||||
dstu2016may:
|
||||
module: "org.hl7.fhir.dstu2016may"
|
||||
r4:
|
||||
module: "org.hl7.fhir.r4"
|
||||
r5:
|
||||
module: "org.hl7.fhir.r5"
|
||||
validator:
|
||||
module: "org.hl7.fhir.validation"
|
||||
maxParallel: 3
|
||||
|
||||
pool:
|
||||
vmImage: "ubuntu-16.04"
|
||||
|
||||
variables:
|
||||
currentModule: $(module)
|
||||
|
||||
steps:
|
||||
# Debugging output to identify current module.
|
||||
- bash: echo Publishing SNAPSHOT for $(module)
|
||||
displayName: 'Print module name.'
|
||||
|
||||
# Signing, for now, occurs for all builds, SNAPSHOT or release. So we need a valid
|
||||
# signing key. The next two steps download the public and private keys from the
|
||||
# secure library files.
|
||||
- task: DownloadSecureFile@1
|
||||
displayName: 'Download public key.'
|
||||
inputs:
|
||||
secureFile: public.key
|
||||
|
||||
- task: DownloadSecureFile@1
|
||||
displayName: 'Download private key.'
|
||||
inputs:
|
||||
secureFile: private.key
|
||||
|
||||
# Import both the private and public keys into gpg for signing.
|
||||
- bash: |
|
||||
gpg --import --no-tty --batch --yes $(Agent.TempDirectory)/public.key
|
||||
gpg --import --no-tty --batch --yes $(Agent.TempDirectory)/private.key
|
||||
gpg --list-keys --keyid-format LONG
|
||||
gpg --list-secret-keys --keyid-format LONG
|
||||
displayName: 'Import signing keys.'
|
||||
|
||||
# For creating the snapshot release with maven, we need to build a fake settings.xml
|
||||
# for it to read from. This is done for the master branch merges only.
|
||||
- bash: |
|
||||
cat >$(System.DefaultWorkingDirectory)/settings.xml <<EOL
|
||||
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
|
||||
https://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||
<servers>
|
||||
<server>
|
||||
<id>ossrh</id>
|
||||
<username>$(SONATYPE_USER)</username>
|
||||
<password>$(SONATYPE_PASS)</password>
|
||||
</server>
|
||||
<server>
|
||||
<id>sonatype-nexus-snapshots</id>
|
||||
<username>$(SONATYPE_USER)</username>
|
||||
<password>$(SONATYPE_PASS)</password>
|
||||
</server>
|
||||
<server>
|
||||
<id>sonatype-nexus-staging</id>
|
||||
<username>$(SONATYPE_USER)</username>
|
||||
<password>$(SONATYPE_PASS)</password>
|
||||
</server>
|
||||
<server>
|
||||
<id>$(PGP_KEYNAME)</id>
|
||||
<passphrase>$(PGP_PASSPHRASE)</passphrase>
|
||||
</server>
|
||||
</servers>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>release</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<gpg.keyname>$(PGP_KEYNAME)</gpg.keyname>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
</settings>
|
||||
EOL
|
||||
displayName: 'Create .mvn/settings.xml'
|
||||
|
||||
# Deploy the SNAPSHOT artifact to sonatype nexus.
|
||||
# This is done for the master branch merges only.
|
||||
- task: Maven@3
|
||||
displayName: 'Deploy $(module) to Sonatype staging'
|
||||
inputs:
|
||||
mavenPomFile: '$(System.DefaultWorkingDirectory)/$(module)/pom.xml'
|
||||
goals: deploy
|
||||
options: '--settings $(System.DefaultWorkingDirectory)/settings.xml '
|
||||
publishJUnitResults: false
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.0.2-SNAPSHOT</version>
|
||||
<version>5.0.5-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.0.2-SNAPSHOT</version>
|
||||
<version>5.0.5-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.0.2-SNAPSHOT</version>
|
||||
<version>5.0.5-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.0.2-SNAPSHOT</version>
|
||||
<version>5.0.5-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.0.2-SNAPSHOT</version>
|
||||
<version>5.0.5-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package org.hl7.fhir.r4.formats;
|
||||
|
||||
import java.awt.im.InputContext;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
|
@ -169,5 +171,12 @@ public abstract class FormatUtilities {
|
|||
return parser.parse(src);
|
||||
}
|
||||
|
||||
public static Resource loadFile(InputStream source) throws FileNotFoundException, IOException, FHIRException {
|
||||
byte[] src = TextFile.streamToBytes(source);
|
||||
FhirFormat fmt = determineFormat(src);
|
||||
ParserBase parser = makeParser(fmt);
|
||||
return parser.parse(src);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.0.2-SNAPSHOT</version>
|
||||
<version>5.0.5-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -1403,7 +1403,7 @@ public class OldProfileComparer implements ProfileKnowledgeProvider {
|
|||
}
|
||||
|
||||
private void genValueSetFile(String filename, ValueSet vs) throws IOException, FHIRException, EOperationOutcome {
|
||||
RenderingContext rc = new RenderingContext(context, null, null, "", "http://hl7.org/fhir", ResourceRendererMode.RESOURCE);
|
||||
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
|
||||
rc.setNoSlowLookup(true);
|
||||
RendererFactory.factory(vs, rc).render(vs);
|
||||
String s = new XhtmlComposer(XhtmlComposer.HTML).compose(vs.getText().getDiv());
|
||||
|
|
|
@ -1391,7 +1391,7 @@ public class ProfileComparer implements ProfileKnowledgeProvider {
|
|||
}
|
||||
|
||||
private void genValueSetFile(String filename, ValueSet vs) throws IOException, FHIRException, EOperationOutcome {
|
||||
RenderingContext rc = new RenderingContext(context, null, null, "", "http://hl7.org/fhir", ResourceRendererMode.RESOURCE);
|
||||
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
|
||||
rc.setNoSlowLookup(true);
|
||||
RendererFactory.factory(vs, rc).render(vs);
|
||||
String s = new XhtmlComposer(XhtmlComposer.HTML).compose(vs.getText().getDiv());
|
||||
|
|
|
@ -533,9 +533,6 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
baseSnapshot = cloneSnapshot(baseSnapshot, base.getType(), derivedType);
|
||||
}
|
||||
if (derived.getUrl().equals("http://sharedhealth.exchange/fhir/StructureDefinition/profile-operationoutcome")) {
|
||||
debug = true;
|
||||
}
|
||||
processPaths("", derived.getSnapshot(), baseSnapshot, diff, baseCursor, diffCursor, baseSnapshot.getElement().size()-1,
|
||||
derived.getDifferential().hasElement() ? derived.getDifferential().getElement().size()-1 : -1, url, webUrl, derived.present(), null, null, false, base.getUrl(), null, false, null, new ArrayList<ElementRedirection>(), base);
|
||||
if (derived.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
||||
|
@ -901,6 +898,9 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
baseCursor++;
|
||||
} else if (diffMatches.size() == 1 && (slicingDone || (!isImplicitSlicing(diffMatches.get(0), cpath) && !(diffMatches.get(0).hasSlicing() || (isExtension(diffMatches.get(0)) && diffMatches.get(0).hasSliceName()))))) {// one matching element in the differential
|
||||
ElementDefinition template = null;
|
||||
if (diffMatches.get(0).hasType() && "Reference".equals(diffMatches.get(0).getType().get(0).getWorkingCode()) && !isValidType(diffMatches.get(0).getType().get(0), currentBase)) {
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.VALIDATION_VAL_ILLEGAL_TYPE_CONSTRAINT, url, diffMatches.get(0).getPath(), diffMatches.get(0).getType().get(0), currentBase.typeSummary()));
|
||||
}
|
||||
if (diffMatches.get(0).hasType() && diffMatches.get(0).getType().size() == 1 && diffMatches.get(0).getType().get(0).hasProfile() && !"Reference".equals(diffMatches.get(0).getType().get(0).getWorkingCode())) {
|
||||
CanonicalType p = diffMatches.get(0).getType().get(0).getProfile().get(0);
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p.getValue());
|
||||
|
@ -915,8 +915,16 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
}
|
||||
if (sd != null) {
|
||||
checkNotGenerating(sd, "an extension definition");
|
||||
if (!sd.hasSnapshot()) {
|
||||
if (!isMatchingType(sd, diffMatches.get(0).getType())) {
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.VALIDATION_VAL_PROFILE_WRONGTYPE2, sd.getUrl(), diffMatches.get(0).getPath(), sd.getType(), p.getValue(), diffMatches.get(0).getType().get(0).getWorkingCode()));
|
||||
}
|
||||
if (isGenerating(sd)) {
|
||||
// this is a special case, because we're only going to access the first element, and we can rely on the fact that it's already populated.
|
||||
// but we check anyway
|
||||
if (sd.getSnapshot().getElementFirstRep().isEmpty()) {
|
||||
throw new FHIRException(context.formatMessage(I18nConstants.ATTEMPT_TO_USE_A_SNAPSHOT_ON_PROFILE__AS__BEFORE_IT_IS_GENERATED, sd.getUrl(), "Source for first element"));
|
||||
}
|
||||
} else if (!sd.hasSnapshot()) {
|
||||
StructureDefinition sdb = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
if (sdb == null)
|
||||
throw new DefinitionException(context.formatMessage(I18nConstants.UNABLE_TO_FIND_BASE__FOR_, sd.getBaseDefinition(), sd.getUrl()));
|
||||
|
@ -1445,7 +1453,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (!diffMatches.get(0).hasSliceName()) { // it's not real content, just the slice
|
||||
diffpos++;
|
||||
}
|
||||
if (hasInnerDiffMatches(differential, cpath, diffpos, diffLimit, base.getElement(), false)) {
|
||||
if (hasInnerDiffMatches(differential, cpath, diffCursor, diffLimit, base.getElement(), false)) {
|
||||
int nbl = findEndOfElement(base, baseCursor);
|
||||
int ndx = differential.getElement().indexOf(diffMatches.get(0));
|
||||
int ndc = ndx+(diffMatches.get(0).hasSlicing() ? 1 : 0);
|
||||
|
@ -1603,6 +1611,35 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
return res;
|
||||
}
|
||||
|
||||
private boolean isMatchingType(StructureDefinition sd, List<TypeRefComponent> types) {
|
||||
while (sd != null) {
|
||||
for (TypeRefComponent tr : types) {
|
||||
if (sd.getType().equals(tr.getCode())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isValidType(TypeRefComponent t, ElementDefinition base) {
|
||||
for (TypeRefComponent tr : base.getType()) {
|
||||
if (tr.getCode().equals(t.getCode())) {
|
||||
return true;
|
||||
}
|
||||
if (tr.getWorkingCode().equals(t.getCode())) {
|
||||
System.out.println("Type error: use of a simple type \""+t.getCode()+"\" wrongly constraining "+base.getPath());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isGenerating(StructureDefinition sd) {
|
||||
return sd.hasUserData("profileutils.snapshot.generating");
|
||||
}
|
||||
|
||||
|
||||
private void checkNotGenerating(StructureDefinition sd, String role) {
|
||||
if (sd.hasUserData("profileutils.snapshot.generating")) {
|
||||
|
@ -3111,10 +3148,16 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
|
||||
|
||||
private ElementDefinition getElementByName(List<ElementDefinition> elements, String contentReference) {
|
||||
for (ElementDefinition ed : elements)
|
||||
if (ed.hasSliceName() && ("#"+ed.getSliceName()).equals(contentReference))
|
||||
for (ElementDefinition ed : elements) {
|
||||
if (("#"+ed.getPath()).equals(contentReference)) {
|
||||
return ed;
|
||||
return null;
|
||||
}
|
||||
if (("#"+ed.getId()).equals(contentReference)) {
|
||||
return ed;
|
||||
}
|
||||
}
|
||||
throw new Error("getElementByName: can't find "+contentReference+"in "+elements.toString());
|
||||
// return null;
|
||||
}
|
||||
|
||||
private ElementDefinition getElementById(List<ElementDefinition> elements, String contentReference) {
|
||||
|
|
|
@ -260,7 +260,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
}
|
||||
|
||||
public void loadFromFile(InputStream stream, String name, IContextResourceLoader loader) throws IOException, FHIRException {
|
||||
loadFromFile(stream, name, null);
|
||||
loadFromFile(stream, name, loader, null);
|
||||
}
|
||||
|
||||
public void loadFromFile(InputStream stream, String name, IContextResourceLoader loader, ILoadFilter filter) throws IOException, FHIRException {
|
||||
|
|
|
@ -68,6 +68,24 @@ public class Property {
|
|||
return definition.getPath().substring(definition.getPath().lastIndexOf(".")+1);
|
||||
}
|
||||
|
||||
public String getXmlName() {
|
||||
if (definition.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-xml-name")) {
|
||||
return ToolingExtensions.readStringExtension(definition, "http://hl7.org/fhir/StructureDefinition/elementdefinition-xml-name");
|
||||
} else {
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
|
||||
public String getXmlNamespace() {
|
||||
if (ToolingExtensions.hasExtension(definition, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace")) {
|
||||
return ToolingExtensions.readStringExtension(definition, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace");
|
||||
} else if (ToolingExtensions.hasExtension(structure, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace")) {
|
||||
return ToolingExtensions.readStringExtension(structure, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace");
|
||||
} else {
|
||||
return FormatUtilities.FHIR_NS;
|
||||
}
|
||||
}
|
||||
|
||||
public ElementDefinition getDefinition() {
|
||||
return definition;
|
||||
}
|
||||
|
@ -199,14 +217,6 @@ public class Property {
|
|||
return definition.getBase().getPath();
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
if (ToolingExtensions.hasExtension(definition, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"))
|
||||
return ToolingExtensions.readStringExtension(definition, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace");
|
||||
if (ToolingExtensions.hasExtension(structure, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"))
|
||||
return ToolingExtensions.readStringExtension(structure, "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace");
|
||||
return FormatUtilities.FHIR_NS;
|
||||
}
|
||||
|
||||
private boolean isElementWithOnlyExtension(final ElementDefinition ed, final List<ElementDefinition> children) {
|
||||
boolean result = false;
|
||||
if (!ed.getType().isEmpty()) {
|
||||
|
|
|
@ -47,18 +47,18 @@ import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
|||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.utils.SnomedExpressions;
|
||||
import org.hl7.fhir.r5.utils.SnomedExpressions.Expression;
|
||||
import org.hl7.fhir.r5.utils.formats.Turtle;
|
||||
import org.hl7.fhir.r5.utils.formats.Turtle.Complex;
|
||||
import org.hl7.fhir.r5.utils.formats.Turtle.Section;
|
||||
import org.hl7.fhir.r5.utils.formats.Turtle.Subject;
|
||||
import org.hl7.fhir.r5.utils.formats.Turtle.TTLComplex;
|
||||
import org.hl7.fhir.r5.utils.formats.Turtle.TTLList;
|
||||
import org.hl7.fhir.r5.utils.formats.Turtle.TTLLiteral;
|
||||
import org.hl7.fhir.r5.utils.formats.Turtle.TTLObject;
|
||||
import org.hl7.fhir.r5.utils.formats.Turtle.TTLURL;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||
import org.hl7.fhir.utilities.turtle.Turtle;
|
||||
import org.hl7.fhir.utilities.turtle.Turtle.Complex;
|
||||
import org.hl7.fhir.utilities.turtle.Turtle.Section;
|
||||
import org.hl7.fhir.utilities.turtle.Turtle.Subject;
|
||||
import org.hl7.fhir.utilities.turtle.Turtle.TTLComplex;
|
||||
import org.hl7.fhir.utilities.turtle.Turtle.TTLList;
|
||||
import org.hl7.fhir.utilities.turtle.Turtle.TTLLiteral;
|
||||
import org.hl7.fhir.utilities.turtle.Turtle.TTLObject;
|
||||
import org.hl7.fhir.utilities.turtle.Turtle.TTLURL;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
||||
|
||||
|
|
|
@ -235,11 +235,7 @@ public class XmlParser extends ParserBase {
|
|||
if (policy == ValidationPolicy.EVERYTHING) {
|
||||
if (empty(element) && FormatUtilities.FHIR_NS.equals(element.getNamespaceURI())) // this rule only applies to FHIR Content
|
||||
logError(line(element), col(element), path, IssueType.INVALID, context.formatMessage(I18nConstants.ELEMENT_MUST_HAVE_SOME_CONTENT), IssueSeverity.ERROR);
|
||||
String ns = FormatUtilities.FHIR_NS;
|
||||
if (ToolingExtensions.hasExtension(prop.getDefinition(), "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"))
|
||||
ns = ToolingExtensions.readStringExtension(prop.getDefinition(), "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace");
|
||||
else if (ToolingExtensions.hasExtension(prop.getStructure(), "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"))
|
||||
ns = ToolingExtensions.readStringExtension(prop.getStructure(), "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace");
|
||||
String ns = prop.getXmlNamespace();
|
||||
if (!element.getNamespaceURI().equals(ns))
|
||||
logError(line(element), col(element), path, IssueType.INVALID, context.formatMessage(I18nConstants.WRONG_NAMESPACE__EXPECTED_, ns), IssueSeverity.ERROR);
|
||||
}
|
||||
|
@ -304,7 +300,7 @@ public class XmlParser extends ParserBase {
|
|||
logError(line, col, path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.XML_ATTR_VALUE_INVALID, attr.getNodeName()), IssueSeverity.ERROR);
|
||||
}
|
||||
if (!(attr.getNodeName().equals("xmlns") || attr.getNodeName().startsWith("xmlns:"))) {
|
||||
Property property = getAttrProp(properties, attr.getNodeName());
|
||||
Property property = getAttrProp(properties, attr.getLocalName(), attr.getNamespaceURI());
|
||||
if (property != null) {
|
||||
String av = attr.getNodeValue();
|
||||
if (ToolingExtensions.hasExtension(property.getDefinition(), "http://www.healthintersections.com.au/fhir/StructureDefinition/elementdefinition-dateformat"))
|
||||
|
@ -331,7 +327,7 @@ public class XmlParser extends ParserBase {
|
|||
Node child = node.getFirstChild();
|
||||
while (child != null) {
|
||||
if (child.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Property property = getElementProp(properties, child.getLocalName());
|
||||
Property property = getElementProp(properties, child.getLocalName(), child.getNamespaceURI());
|
||||
if (property != null) {
|
||||
if (!property.isChoice() && "xhtml".equals(property.getType())) {
|
||||
XhtmlNode xhtml;
|
||||
|
@ -401,7 +397,7 @@ public class XmlParser extends ParserBase {
|
|||
}
|
||||
|
||||
|
||||
private Property getElementProp(List<Property> properties, String nodeName) {
|
||||
private Property getElementProp(List<Property> properties, String nodeName, String namespace) {
|
||||
List<Property> propsSortedByLongestFirst = new ArrayList<Property>(properties);
|
||||
// sort properties according to their name longest first, so .requestOrganizationReference comes first before .request[x]
|
||||
// and therefore the longer property names get evaluated first
|
||||
|
@ -411,22 +407,37 @@ public class XmlParser extends ParserBase {
|
|||
return o2.getName().length() - o1.getName().length();
|
||||
}
|
||||
});
|
||||
for (Property p : propsSortedByLongestFirst)
|
||||
if (!p.getDefinition().hasRepresentation(PropertyRepresentation.XMLATTR) && !p.getDefinition().hasRepresentation(
|
||||
PropertyRepresentation.XMLTEXT)) {
|
||||
if (p.getName().equals(nodeName))
|
||||
return p;
|
||||
if (p.getName().endsWith("[x]") && nodeName.length() > p.getName().length()-3 && p.getName().substring(0, p.getName().length()-3).equals(nodeName.substring(0, p.getName().length()-3)))
|
||||
return p;
|
||||
}
|
||||
// first scan, by namespace
|
||||
for (Property p : propsSortedByLongestFirst) {
|
||||
if (!p.getDefinition().hasRepresentation(PropertyRepresentation.XMLATTR) && !p.getDefinition().hasRepresentation(PropertyRepresentation.XMLTEXT)) {
|
||||
if (p.getXmlName().equals(nodeName) && p.getXmlNamespace().equals(namespace))
|
||||
return p;
|
||||
}
|
||||
}
|
||||
for (Property p : propsSortedByLongestFirst) {
|
||||
if (!p.getDefinition().hasRepresentation(PropertyRepresentation.XMLATTR) && !p.getDefinition().hasRepresentation(PropertyRepresentation.XMLTEXT)) {
|
||||
if (p.getXmlName().equals(nodeName))
|
||||
return p;
|
||||
if (p.getName().endsWith("[x]") && nodeName.length() > p.getName().length()-3 && p.getName().substring(0, p.getName().length()-3).equals(nodeName.substring(0, p.getName().length()-3)))
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Property getAttrProp(List<Property> properties, String nodeName) {
|
||||
for (Property p : properties)
|
||||
if (p.getName().equals(nodeName) && p.getDefinition().hasRepresentation(
|
||||
PropertyRepresentation.XMLATTR))
|
||||
return p;
|
||||
private Property getAttrProp(List<Property> properties, String nodeName, String namespace) {
|
||||
for (Property p : properties) {
|
||||
if (p.getXmlName().equals(nodeName) && p.getDefinition().hasRepresentation(PropertyRepresentation.XMLATTR) && p.getXmlNamespace().equals(namespace)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
if (namespace == null) {
|
||||
for (Property p : properties) {
|
||||
if (p.getXmlName().equals(nodeName) && p.getDefinition().hasRepresentation(PropertyRepresentation.XMLATTR)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -524,7 +535,7 @@ public class XmlParser extends ParserBase {
|
|||
xml.setSortAttributes(false);
|
||||
xml.setPretty(style == OutputStyle.PRETTY);
|
||||
xml.start();
|
||||
xml.setDefaultNamespace(e.getProperty().getNamespace());
|
||||
xml.setDefaultNamespace(e.getProperty().getXmlNamespace());
|
||||
if (hasTypeAttr(e))
|
||||
xml.namespace("http://www.w3.org/2001/XMLSchema-instance", "xsi");
|
||||
composeElement(xml, e, e.getType(), true);
|
||||
|
@ -545,7 +556,7 @@ public class XmlParser extends ParserBase {
|
|||
|
||||
public void compose(Element e, IXMLWriter xml) throws Exception {
|
||||
xml.start();
|
||||
xml.setDefaultNamespace(e.getProperty().getNamespace());
|
||||
xml.setDefaultNamespace(e.getProperty().getXmlNamespace());
|
||||
composeElement(xml, e, e.getType(), true);
|
||||
xml.end();
|
||||
}
|
||||
|
|
|
@ -38,8 +38,8 @@ package org.hl7.fhir.r5.formats;
|
|||
|
||||
|
||||
import org.hl7.fhir.r5.model.*;
|
||||
import org.hl7.fhir.r5.utils.formats.Turtle.Complex;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.turtle.Turtle.Complex;
|
||||
|
||||
public class RdfParser extends RdfParserBase {
|
||||
|
||||
|
|
|
@ -43,10 +43,10 @@ import org.hl7.fhir.r5.model.Coding;
|
|||
import org.hl7.fhir.r5.model.DataType;
|
||||
import org.hl7.fhir.r5.model.Enumeration;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.utils.formats.Turtle;
|
||||
import org.hl7.fhir.r5.utils.formats.Turtle.Complex;
|
||||
import org.hl7.fhir.r5.utils.formats.Turtle.Section;
|
||||
import org.hl7.fhir.r5.utils.formats.Turtle.Subject;
|
||||
import org.hl7.fhir.utilities.turtle.Turtle;
|
||||
import org.hl7.fhir.utilities.turtle.Turtle.Complex;
|
||||
import org.hl7.fhir.utilities.turtle.Turtle.Section;
|
||||
import org.hl7.fhir.utilities.turtle.Turtle.Subject;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
public abstract class RdfParserBase extends ParserBase implements IParser {
|
||||
|
|
|
@ -1,33 +1,33 @@
|
|||
package org.hl7.fhir.r5.formats;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
@ -181,7 +181,6 @@ public abstract class XmlParserBase extends ParserBase implements IParser {
|
|||
writer.end();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compose a type to a stream (used in the spec, for example, but not normally in production)
|
||||
* @
|
||||
|
|
|
@ -15,6 +15,10 @@ import org.hl7.fhir.r5.model.Bundle.BundleEntrySearchComponent;
|
|||
import org.hl7.fhir.r5.model.Bundle.BundleType;
|
||||
import org.hl7.fhir.r5.model.Composition;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Provenance;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
import org.hl7.fhir.r5.utils.EOperationOutcome;
|
||||
|
@ -37,17 +41,58 @@ public class BundleRenderer extends ResourceRenderer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String display(DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
public String display(Resource r) throws UnsupportedEncodingException, IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean render(XhtmlNode x, ResourceWrapper b) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
|
||||
List<BaseWrapper> entries = b.children("entry");
|
||||
if ("document".equals(b.get("type").primitiveValue())) {
|
||||
if (entries.isEmpty() || (entries.get(0).has("resource") && "Composition".equals(entries.get(0).get("resource").fhirType())))
|
||||
throw new FHIRException("Invalid document - first entry is not a Composition");
|
||||
ResourceWrapper r = (ResourceWrapper) entries.get(0).getChildByName("resource").getValues().get(0);
|
||||
x.addChildren(r.getNarrative());
|
||||
} else if ("collection".equals(b.get("type").primitiveValue()) && allEntriesAreHistoryProvenance(entries)) {
|
||||
// nothing
|
||||
} else {
|
||||
XhtmlNode root = new XhtmlNode(NodeType.Element, "div");
|
||||
root.para().addText("Bundle "+b.getId()+" of type "+b.get("type").primitiveValue());
|
||||
int i = 0;
|
||||
for (BaseWrapper be : entries) {
|
||||
i++;
|
||||
if (be.has("fullUrl")) {
|
||||
root.an(makeInternalLink(be.get("fullUrl").primitiveValue()));
|
||||
}
|
||||
if (be.has("resource") && be.getChildByName("resource").getValues().get(0).has("id")) {
|
||||
root.an(be.get("resource").fhirType().toLowerCase() + "_" + be.getChildByName("resource").getValues().get(0).get("id").primitiveValue());
|
||||
}
|
||||
root.hr();
|
||||
root.para().addText("Entry "+Integer.toString(i)+(be.has("fullUrl") ? " - Full URL = " + be.get("fullUrl").primitiveValue() : ""));
|
||||
// if (be.hasRequest())
|
||||
// renderRequest(root, be.getRequest());
|
||||
// if (be.hasSearch())
|
||||
// renderSearch(root, be.getSearch());
|
||||
// if (be.hasResponse())
|
||||
// renderResponse(root, be.getResponse());
|
||||
if (be.has("resource")) {
|
||||
root.para().addText("Resource "+be.get("resource").fhirType()+":");
|
||||
ResourceWrapper rw = be.getChildByName("resource").getAsResource();
|
||||
root.blockquote().addChildren(rw.getNarrative());
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public XhtmlNode render(Bundle b) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
|
||||
if (b.getType() == BundleType.DOCUMENT) {
|
||||
if (!b.hasEntry() || !(b.getEntryFirstRep().hasResource() && b.getEntryFirstRep().getResource() instanceof Composition))
|
||||
throw new FHIRException("Invalid document - first entry is not a Composition");
|
||||
Composition dr = (Composition) b.getEntryFirstRep().getResource();
|
||||
return dr.getText().getDiv();
|
||||
} else if ((b.getType() == BundleType.DOCUMENT && allEntresAreHistoryProvenance(b))) {
|
||||
} else if ((b.getType() == BundleType.COLLECTION && allEntresAreHistoryProvenance(b))) {
|
||||
return null;
|
||||
} else {
|
||||
XhtmlNode root = new XhtmlNode(NodeType.Element, "div");
|
||||
|
@ -80,9 +125,22 @@ public class BundleRenderer extends ResourceRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean allEntriesAreHistoryProvenance(List<BaseWrapper> entries) throws UnsupportedEncodingException, FHIRException, IOException {
|
||||
for (BaseWrapper be : entries) {
|
||||
if (!"Provenance".equals(be.get("resource").fhirType())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return !entries.isEmpty();
|
||||
}
|
||||
|
||||
private boolean allEntresAreHistoryProvenance(Bundle b) {
|
||||
return false;
|
||||
for (BundleEntryComponent be : b.getEntry()) {
|
||||
if (!(be.getResource() instanceof Provenance)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return !b.getEntry().isEmpty();
|
||||
}
|
||||
|
||||
private List<XhtmlNode> checkInternalLinks(Bundle b, List<XhtmlNode> childNodes) {
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.io.UnsupportedEncodingException;
|
|||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestComponent;
|
||||
import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
|
||||
|
@ -81,7 +82,7 @@ public class CapabilityStatementRenderer extends ResourceRenderer {
|
|||
tr = t.tr();
|
||||
tr.td().addText(r.getType());
|
||||
if (r.hasProfile()) {
|
||||
tr.td().ah(context.getPrefix()+r.getProfile()).addText(r.getProfile());
|
||||
tr.td().ah(r.getProfile()).addText(r.getProfile());
|
||||
}
|
||||
tr.td().addText(showOp(r, TypeRestfulInteraction.READ));
|
||||
if (hasVRead)
|
||||
|
@ -112,7 +113,7 @@ public class CapabilityStatementRenderer extends ResourceRenderer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String display(DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
public String display(Resource r) throws UnsupportedEncodingException, IOException {
|
||||
return ((CapabilityStatement) r).present();
|
||||
}
|
||||
|
||||
|
|
|
@ -414,7 +414,7 @@ public class CodeSystemRenderer extends TerminologyRenderer {
|
|||
first = false;
|
||||
XhtmlNode span = td.span(null, mapping.comp.hasRelationship() ? mapping.comp.getRelationship().toCode() : "");
|
||||
span.addText(getCharForRelationship(mapping.comp));
|
||||
a = td.ah(getContext().getPrefix()+m.getLink()+"#"+makeAnchor(mapping.group.getTarget(), mapping.comp.getCode()));
|
||||
a = td.ah(getContext().getSpecificationLink()+m.getLink()+"#"+makeAnchor(mapping.group.getTarget(), mapping.comp.getCode()));
|
||||
a.addText(mapping.comp.getCode());
|
||||
if (!Utilities.noString(mapping.comp.getComment()))
|
||||
td.i().tx("("+mapping.comp.getComment()+")");
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.io.UnsupportedEncodingException;
|
|||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StringType;
|
||||
import org.hl7.fhir.r5.model.CompartmentDefinition;
|
||||
import org.hl7.fhir.r5.model.CompartmentDefinition.CompartmentDefinitionResourceComponent;
|
||||
|
@ -67,7 +68,7 @@ public class CompartmentDefinitionRenderer extends ResourceRenderer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String display(DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
public String display(Resource r) throws UnsupportedEncodingException, IOException {
|
||||
return ((CompartmentDefinition) r).present();
|
||||
}
|
||||
|
||||
|
|
|
@ -375,7 +375,7 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
|||
if (cs == null)
|
||||
td.tx(url);
|
||||
else
|
||||
td.ah(cs.getUserString("path")).attribute("title", url).tx(cs.present());
|
||||
td.ah(context.fixReference(cs.getUserString("path"))).attribute("title", url).tx(cs.present());
|
||||
}
|
||||
|
||||
private void addUnmapped(XhtmlNode tbl, ConceptMapGroupComponent grp) {
|
||||
|
|
|
@ -61,7 +61,7 @@ public class DataRenderer {
|
|||
|
||||
public DataRenderer(IWorkerContext worker) {
|
||||
super();
|
||||
this.context = new RenderingContext(worker, new MarkDownProcessor(Dialect.COMMON_MARK), ValidationOptions.defaults(), "", null, ResourceRendererMode.RESOURCE);
|
||||
this.context = new RenderingContext(worker, new MarkDownProcessor(Dialect.COMMON_MARK), ValidationOptions.defaults(), "http://hl7.org/fhir/R4", "", null, ResourceRendererMode.RESOURCE);
|
||||
}
|
||||
|
||||
// -- 2. Markdown support -------------------------------------------------------
|
||||
|
@ -218,7 +218,7 @@ public class DataRenderer {
|
|||
// -- 5. Data type Rendering ----------------------------------------------
|
||||
|
||||
public static String display(IWorkerContext context, DataType type) {
|
||||
return new DataRenderer(new RenderingContext(context, null, null, "", null, ResourceRendererMode.RESOURCE)).display(type);
|
||||
return new DataRenderer(new RenderingContext(context, null, null, "http://hl7.org/fhir/R4", "", null, ResourceRendererMode.RESOURCE)).display(type);
|
||||
}
|
||||
|
||||
public String displayBase(Base b) {
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.hl7.fhir.exceptions.DefinitionException;
|
|||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.DiagnosticReport;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.PropertyWrapper;
|
||||
|
@ -126,7 +127,7 @@ public class DiagnosticReportRenderer extends ResourceRenderer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String display(DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
public String display(Resource r) throws UnsupportedEncodingException, IOException {
|
||||
return display((DiagnosticReport) r);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.io.IOException;
|
|||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
|
@ -19,7 +20,7 @@ public class EncounterRenderer extends ResourceRenderer {
|
|||
return false;
|
||||
}
|
||||
|
||||
public String display(DomainResource dr) {
|
||||
public String display(Resource dr) {
|
||||
return "Not done yet";
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import org.hl7.fhir.exceptions.DefinitionException;
|
|||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.ImplementationGuide;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
@ -42,7 +43,7 @@ public class ImplementationGuideRenderer extends ResourceRenderer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String display(DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
public String display(Resource r) throws UnsupportedEncodingException, IOException {
|
||||
return ((ImplementationGuide) r).present();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import org.hl7.fhir.exceptions.DefinitionException;
|
|||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
|
@ -51,7 +52,7 @@ public class LiquidRenderer extends ResourceRenderer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String display(DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
public String display(Resource r) throws UnsupportedEncodingException, IOException {
|
||||
return "not done yet";
|
||||
}
|
||||
|
||||
|
@ -61,7 +62,7 @@ public class LiquidRenderer extends ResourceRenderer {
|
|||
XhtmlNode xn;
|
||||
try {
|
||||
LiquidDocument doc = engine.parse(liquidTemplate, "template");
|
||||
String html = "rto do"; // engine.evaluate(doc, r, rcontext);
|
||||
String html = engine.evaluate(doc, r.getBase(), rcontext);
|
||||
xn = new XhtmlParser().parseFragment(html);
|
||||
if (!x.getName().equals("div"))
|
||||
throw new FHIRException("Error in template: Root element is not 'div'");
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.hl7.fhir.r5.model.DomainResource;
|
|||
import org.hl7.fhir.r5.model.ListResource;
|
||||
import org.hl7.fhir.r5.model.ListResource.ListResourceEntryComponent;
|
||||
import org.hl7.fhir.r5.model.Reference;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
|
||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
|
@ -183,7 +184,7 @@ public class ListRenderer extends ResourceRenderer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String display(DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
public String display(Resource r) throws UnsupportedEncodingException, IOException {
|
||||
return ((ListResource) r).getTitle();
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.hl7.fhir.r5.model.DomainResource;
|
|||
import org.hl7.fhir.r5.model.NamingSystem;
|
||||
import org.hl7.fhir.r5.model.NamingSystem.NamingSystemUniqueIdComponent;
|
||||
import org.hl7.fhir.r5.model.PrimitiveType;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
|
@ -120,7 +121,7 @@ public class NamingSystemRenderer extends ResourceRenderer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String display(DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
public String display(Resource r) throws UnsupportedEncodingException, IOException {
|
||||
return ((NamingSystem) r).present();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.hl7.fhir.r5.model.DomainResource;
|
|||
import org.hl7.fhir.r5.model.Extension;
|
||||
import org.hl7.fhir.r5.model.OperationDefinition;
|
||||
import org.hl7.fhir.r5.model.OperationDefinition.OperationDefinitionParameterComponent;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
|
@ -74,7 +75,7 @@ public class OperationDefinitionRenderer extends TerminologyRenderer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String display(DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
public String display(Resource r) throws UnsupportedEncodingException, IOException {
|
||||
return ((OperationDefinition) r).present();
|
||||
}
|
||||
|
||||
|
@ -104,7 +105,7 @@ public class OperationDefinitionRenderer extends TerminologyRenderer {
|
|||
if (p.hasSearchType()) {
|
||||
td.br();
|
||||
td.tx("(");
|
||||
td.ah( context.getPrefix() == null ? "search.html#"+p.getSearchType().toCode() : Utilities.pathURL(context.getPrefix(), "search.html#"+p.getSearchType().toCode())).tx(p.getSearchType().toCode());
|
||||
td.ah( context.getSpecificationLink() == null ? "search.html#"+p.getSearchType().toCode() : Utilities.pathURL(context.getSpecificationLink(), "search.html#"+p.getSearchType().toCode())).tx(p.getSearchType().toCode());
|
||||
td.tx(")");
|
||||
}
|
||||
td = tr.td();
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.hl7.fhir.r5.model.ExtensionHelper;
|
|||
import org.hl7.fhir.r5.model.OperationOutcome;
|
||||
import org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity;
|
||||
import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StringType;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
|
@ -84,7 +85,7 @@ public class OperationOutcomeRenderer extends ResourceRenderer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String display(DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
public String display(Resource r) throws UnsupportedEncodingException, IOException {
|
||||
return display((OperationOutcome) r);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.io.IOException;
|
|||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
|
@ -20,7 +21,7 @@ public class PatientRenderer extends ResourceRenderer {
|
|||
return false;
|
||||
}
|
||||
|
||||
public String display(DomainResource dr) {
|
||||
public String display(Resource dr) {
|
||||
return "Not done yet";
|
||||
}
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String display(DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
public String display(Resource r) throws UnsupportedEncodingException, IOException {
|
||||
return "todo";
|
||||
}
|
||||
//
|
||||
|
@ -213,20 +213,22 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
|||
boolean firstElement = true;
|
||||
boolean last = false;
|
||||
for (PropertyWrapper p : res.children()) {
|
||||
ElementDefinition child = getElementDefinition(profile.getSnapshot().getElement(), path+"."+p.getName(), p);
|
||||
if (p.getValues().size() > 0 && p.getValues().get(0) != null && child != null && isPrimitive(child) && includeInSummary(child)) {
|
||||
if (firstElement)
|
||||
firstElement = false;
|
||||
else if (last)
|
||||
x.tx("; ");
|
||||
boolean first = true;
|
||||
last = false;
|
||||
for (BaseWrapper v : p.getValues()) {
|
||||
if (first)
|
||||
first = false;
|
||||
if (!ignoreProperty(p)) {
|
||||
ElementDefinition child = getElementDefinition(profile.getSnapshot().getElement(), path+"."+p.getName(), p);
|
||||
if (p.getValues().size() > 0 && p.getValues().get(0) != null && child != null && isPrimitive(child) && includeInSummary(child)) {
|
||||
if (firstElement)
|
||||
firstElement = false;
|
||||
else if (last)
|
||||
x.tx(", ");
|
||||
last = displayLeaf(res, v, child, x, p.getName(), showCodeDetails) || last;
|
||||
x.tx("; ");
|
||||
boolean first = true;
|
||||
last = false;
|
||||
for (BaseWrapper v : p.getValues()) {
|
||||
if (first)
|
||||
first = false;
|
||||
else if (last)
|
||||
x.tx(", ");
|
||||
last = displayLeaf(res, v, child, x, p.getName(), showCodeDetails) || last;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,6 +236,10 @@ public class ProfileDrivenRenderer extends ResourceRenderer {
|
|||
}
|
||||
|
||||
|
||||
private boolean ignoreProperty(PropertyWrapper p) {
|
||||
return Utilities.existsInList(p.getName(), "contained");
|
||||
}
|
||||
|
||||
private boolean includeInSummary(ElementDefinition child) {
|
||||
if (child.getIsModifier())
|
||||
return true;
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.hl7.fhir.r5.model.DomainResource;
|
|||
import org.hl7.fhir.r5.model.Provenance;
|
||||
import org.hl7.fhir.r5.model.Provenance.ProvenanceAgentComponent;
|
||||
import org.hl7.fhir.r5.model.Reference;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.UriType;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
@ -141,7 +142,7 @@ public class ProvenanceRenderer extends ResourceRenderer {
|
|||
return hasExtensions;
|
||||
}
|
||||
|
||||
public String display(DomainResource dr) throws UnsupportedEncodingException, IOException {
|
||||
public String display(Resource dr) throws UnsupportedEncodingException, IOException {
|
||||
return display((Provenance) dr);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,18 +2,25 @@ package org.hl7.fhir.r5.renderers;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Expression;
|
||||
import org.hl7.fhir.r5.model.Extension;
|
||||
import org.hl7.fhir.r5.model.Questionnaire;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemAnswerOptionComponent;
|
||||
import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent;
|
||||
import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemEnableWhenComponent;
|
||||
import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemInitialComponent;
|
||||
import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemType;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
|
@ -27,30 +34,24 @@ import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.TableModel;
|
|||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
|
||||
public class QuestionnaireRenderer extends TerminologyRenderer {
|
||||
|
||||
private boolean tree = false;
|
||||
|
||||
|
||||
public QuestionnaireRenderer(RenderingContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public boolean isTree() {
|
||||
return tree;
|
||||
}
|
||||
|
||||
public void setTree(boolean tree) {
|
||||
this.tree = tree;
|
||||
}
|
||||
|
||||
|
||||
public boolean render(XhtmlNode x, DomainResource q) throws UnsupportedEncodingException, IOException {
|
||||
return render(x, (Questionnaire) q);
|
||||
}
|
||||
|
||||
public boolean render(XhtmlNode x, Questionnaire q) throws UnsupportedEncodingException, IOException {
|
||||
if (tree) {
|
||||
return renderTree(x, q);
|
||||
} else {
|
||||
return renderForm(x, q);
|
||||
switch (context.getQuestionnaireMode()) {
|
||||
case FORM: return renderForm(x, q);
|
||||
case LINKS: return renderLinks(x, q);
|
||||
case LOGIC: return renderLogic(x, q);
|
||||
case DEFNS: return renderDefns(x, q);
|
||||
case TREE: return renderTree(x, q);
|
||||
default:
|
||||
throw new Error("Unknown Questionnaire Renderer Mode");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,8 +59,8 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
HierarchicalTableGenerator gen = new HierarchicalTableGenerator(context.getDestDir(), context.isInlineGraphics(), true);
|
||||
TableModel model = gen.new TableModel("qtree="+q.getId(), true);
|
||||
model.setAlternating(true);
|
||||
model.setDocoImg(context.getPrefix() +"help16.png");
|
||||
model.setDocoRef(context.getPrefix()+"formats.html#table");
|
||||
model.setDocoImg(context.getSpecificationLink() +"help16.png");
|
||||
model.setDocoRef(context.getSpecificationLink()+"formats.html#table");
|
||||
model.getTitles().add(gen.new Title(null, model.getDocoRef(), translate("sd.head", "LinkId"), translate("sd.hint", "The linkId for the item"), null, 0));
|
||||
model.getTitles().add(gen.new Title(null, model.getDocoRef(), translate("sd.head", "Text"), translate("sd.hint", "Text for the item"), null, 0));
|
||||
model.getTitles().add(gen.new Title(null, model.getDocoRef(), translate("sd.head", "Cardinality"), translate("sd.hint", "Minimum and Maximum # of times the the itemcan appear in the instance"), null, 0));
|
||||
|
@ -86,19 +87,19 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
String txt = (i.hasPrefix() ? i.getPrefix() + ". " : "") + i.getText();
|
||||
r.getCells().add(gen.new Cell(null, null, txt, null, null));
|
||||
r.getCells().add(gen.new Cell(null, null, (i.getRequired() ? "1" : "0")+".."+(i.getRepeats() ? "*" : "1"), null, null));
|
||||
r.getCells().add(gen.new Cell(null, context.getPrefix()+"codesystem-item-type.html#"+i.getType().toCode(), i.getType().toCode(), null, null));
|
||||
r.getCells().add(gen.new Cell(null, context.getSpecificationLink()+"codesystem-item-type.html#"+i.getType().toCode(), i.getType().toCode(), null, null));
|
||||
|
||||
// flags:
|
||||
Cell flags = gen.new Cell();
|
||||
r.getCells().add(flags);
|
||||
if (i.getReadOnly()) {
|
||||
flags.addPiece(gen.new Piece(Utilities.pathURL(context.getPrefix(), "questionnaire-definitions.html#Questionnaire.item.readOnly"), null, "Is Readonly").addHtml(new XhtmlNode(NodeType.Element, "img").attribute("src", Utilities.path(context.getDestDir(), "icon-qi-readonly.png"))));
|
||||
flags.addPiece(gen.new Piece(Utilities.pathURL(context.getSpecificationLink(), "questionnaire-definitions.html#Questionnaire.item.readOnly"), null, "Is Readonly").addHtml(new XhtmlNode(NodeType.Element, "img").attribute("src", Utilities.path(context.getDestDir(), "icon-qi-readonly.png"))));
|
||||
}
|
||||
if (ToolingExtensions.readBoolExtension(i, "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-isSubject")) {
|
||||
flags.addPiece(gen.new Piece("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-isSubject", null, "Can change the subject of the questionnaire").addHtml(new XhtmlNode(NodeType.Element, "img").attribute("src", Utilities.path(context.getDestDir(), "icon-qi-subject.png"))));
|
||||
}
|
||||
if (ToolingExtensions.readBoolExtension(i, "http://hl7.org/fhir/StructureDefinition/questionnaire-hidden")) {
|
||||
flags.addPiece(gen.new Piece(Utilities.pathURL(context.getPrefix(), "extension-questionnaire-hidden.html"), null, "Is a hidden item").addHtml(new XhtmlNode(NodeType.Element, "img").attribute("src", Utilities.path(context.getDestDir(), "icon-qi-hidden.png"))));
|
||||
flags.addPiece(gen.new Piece(Utilities.pathURL(context.getSpecificationLink(), "extension-questionnaire-hidden.html"), null, "Is a hidden item").addHtml(new XhtmlNode(NodeType.Element, "img").attribute("src", Utilities.path(context.getDestDir(), "icon-qi-hidden.png"))));
|
||||
}
|
||||
if (ToolingExtensions.readBoolExtension(i, "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-optionalDisplay")) {
|
||||
flags.addPiece(gen.new Piece("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-optionalDisplay", null, "Is optional to display").addHtml(new XhtmlNode(NodeType.Element, "img").attribute("src", Utilities.path(context.getDestDir(), "icon-qi-optional.png"))));
|
||||
|
@ -113,7 +114,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
if (i.hasExtension("http://hl7.org/fhir/StructureDefinition/questionnaire-displayCategory")) {
|
||||
CodeableConcept cc = i.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/questionnaire-displayCategory").getValueCodeableConcept();
|
||||
String code = cc.getCode("http://hl7.org/fhir/questionnaire-display-category");
|
||||
flags.addPiece(gen.new Piece("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod", null, "Category: "+code).addHtml(new XhtmlNode(NodeType.Element, "img").attribute("src", Utilities.path(context.getDestDir(), "icon-qi-"+code+".png"))));
|
||||
flags.addPiece(gen.new Piece("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-displayCategory", null, "Category: "+code).addHtml(new XhtmlNode(NodeType.Element, "img").attribute("src", Utilities.path(context.getDestDir(), "icon-qi-"+code+".png"))));
|
||||
}
|
||||
|
||||
Cell defn = gen.new Cell();
|
||||
|
@ -209,11 +210,9 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
for (QuestionnaireItemComponent c : i.getItem()) {
|
||||
hasExt = renderTreeItem(gen, r.getSubRows(), q, c) || hasExt;
|
||||
}
|
||||
return hasExt;
|
||||
|
||||
return hasExt;
|
||||
}
|
||||
|
||||
|
||||
private void addExpression(Piece p, Expression exp, String label, String url) {
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "li").style("font-size: 11px");
|
||||
p.addHtml(x);
|
||||
|
@ -222,6 +221,129 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
x.code(exp.getExpression());
|
||||
}
|
||||
|
||||
private boolean renderLogic(XhtmlNode x, Questionnaire q) throws FHIRException, IOException {
|
||||
HierarchicalTableGenerator gen = new HierarchicalTableGenerator(context.getDestDir(), context.isInlineGraphics(), true);
|
||||
TableModel model = gen.new TableModel("qtree="+q.getId(), true);
|
||||
model.setAlternating(true);
|
||||
model.setDocoImg(context.getSpecificationLink() +"help16.png");
|
||||
model.setDocoRef(context.getSpecificationLink()+"formats.html#table");
|
||||
model.getTitles().add(gen.new Title(null, model.getDocoRef(), translate("sd.head", "LinkId"), translate("sd.hint", "The linkId for the item"), null, 0));
|
||||
model.getTitles().add(gen.new Title(null, model.getDocoRef(), translate("sd.head", "Description & Constraints"), translate("sd.hint", "Additional information about the item"), null, 0));
|
||||
|
||||
boolean hasExt = false;
|
||||
for (QuestionnaireItemComponent i : q.getItem()) {
|
||||
hasExt = renderLogicItem(gen, model.getRows(), q, i) || hasExt;
|
||||
}
|
||||
XhtmlNode xn = gen.generate(model, context.getDestDir(), 1, null);
|
||||
x.getChildNodes().add(xn);
|
||||
return hasExt;
|
||||
}
|
||||
|
||||
private boolean renderLogicItem(HierarchicalTableGenerator gen, List<Row> rows, Questionnaire q, QuestionnaireItemComponent i) throws IOException {
|
||||
Row r = gen.new Row();
|
||||
rows.add(r);
|
||||
boolean hasExt = false;
|
||||
|
||||
r.setIcon("icon-q-"+i.getType().toCode()+".png", i.getType().getDisplay());
|
||||
r.getCells().add(gen.new Cell(null, context.getDefinitionsTarget() == null ? "" : context.getDefinitionsTarget()+"-definitions.html#extension."+i.getLinkId(), i.getLinkId(), null, null));
|
||||
Cell defn = gen.new Cell();
|
||||
r.getCells().add(defn);
|
||||
|
||||
if (i.hasMaxLength()) {
|
||||
defn.getPieces().add(gen.new Piece(null, "Max Length: ", null));
|
||||
defn.getPieces().add(gen.new Piece(null, Integer.toString(i.getMaxLength()), null));
|
||||
}
|
||||
if (i.hasDefinition()) {
|
||||
if (!defn.getPieces().isEmpty()) defn.addPiece(gen.new Piece("br"));
|
||||
defn.getPieces().add(gen.new Piece(null, "Definition: ", null));
|
||||
defn.getPieces().add(gen.new Piece(null, i.getDefinition(), null));
|
||||
|
||||
}
|
||||
if (i.hasEnableWhen()) {
|
||||
if (!defn.getPieces().isEmpty()) defn.addPiece(gen.new Piece("br"));
|
||||
defn.getPieces().add(gen.new Piece(null, "Enable When: ", null));
|
||||
defn.getPieces().add(gen.new Piece(null, "todo", null));
|
||||
}
|
||||
if (i.hasAnswerValueSet()) {
|
||||
if (!defn.getPieces().isEmpty()) defn.addPiece(gen.new Piece("br"));
|
||||
defn.getPieces().add(gen.new Piece(null, "Value Set: ", null));
|
||||
if (i.getAnswerValueSet().startsWith("#")) {
|
||||
ValueSet vs = (ValueSet) q.getContained(i.getAnswerValueSet().substring(1));
|
||||
if (vs == null) {
|
||||
defn.getPieces().add(gen.new Piece(null, i.getAnswerValueSet(), null));
|
||||
} else {
|
||||
defn.getPieces().add(gen.new Piece("todo", vs.present(), null));
|
||||
}
|
||||
} else {
|
||||
ValueSet vs = context.getWorker().fetchResource(ValueSet.class, i.getAnswerValueSet());
|
||||
if (vs == null || !vs.hasUserData("path")) {
|
||||
defn.getPieces().add(gen.new Piece(null, i.getAnswerValueSet(), null));
|
||||
} else {
|
||||
defn.getPieces().add(gen.new Piece(vs.getUserString("path"), vs.present(), null));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i.hasAnswerOption()) {
|
||||
if (!defn.getPieces().isEmpty()) defn.addPiece(gen.new Piece("br"));
|
||||
defn.getPieces().add(gen.new Piece(null, "Options: ", null));
|
||||
defn.getPieces().add(gen.new Piece(context.getDefinitionsTarget()+"#"+i.getLinkId(), Integer.toString(i.getAnswerOption().size())+" "+Utilities.pluralize("option", i.getAnswerOption().size()), null));
|
||||
}
|
||||
if (i.hasInitial()) {
|
||||
for (QuestionnaireItemInitialComponent v : i.getInitial()) {
|
||||
if (!defn.getPieces().isEmpty()) defn.addPiece(gen.new Piece("br"));
|
||||
defn.getPieces().add(gen.new Piece(null, "Initial Value: ", null));
|
||||
defn.getPieces().add(gen.new Piece(null, v.getValue().fhirType(), null));
|
||||
defn.getPieces().add(gen.new Piece(null, " = ", null));
|
||||
if (v.getValue().isPrimitive()) {
|
||||
defn.getPieces().add(gen.new Piece(null, v.getValue().primitiveValue(), null));
|
||||
} else {
|
||||
defn.getPieces().add(gen.new Piece(null, "{todo}", null));
|
||||
}
|
||||
}
|
||||
}
|
||||
// still todo
|
||||
|
||||
//
|
||||
//http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-choiceColumn
|
||||
//
|
||||
//http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-width
|
||||
//http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod
|
||||
//http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl
|
||||
//http://hl7.org/fhir/StructureDefinition/questionnaire-sliderStepValue
|
||||
|
||||
if (i.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression") || i.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-itemContext") || i.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression") || i.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-contextExpression") || i.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-candidateExpression") || i.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression")) {
|
||||
if (!defn.getPieces().isEmpty()) defn.addPiece(gen.new Piece("br"));
|
||||
defn.getPieces().add(gen.new Piece(null, "Expressions: ", null));
|
||||
Piece p = gen.new Piece("ul");
|
||||
defn.getPieces().add(p);
|
||||
for (Extension e : i.getExtensionsByUrl("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression")) {
|
||||
addExpression(p, e.getValueExpression(), "Initial Value", "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression");
|
||||
}
|
||||
for (Extension e : i.getExtensionsByUrl("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-contextExpression")) {
|
||||
addExpression(p, e.getValueExpression(), "Context", "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-contextExpression");
|
||||
}
|
||||
for (Extension e : i.getExtensionsByUrl("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-itemContext")) {
|
||||
addExpression(p, e.getValueExpression(), "Item Context", "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-itemContext");
|
||||
}
|
||||
for (Extension e : i.getExtensionsByUrl("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression")) {
|
||||
addExpression(p, e.getValueExpression(), "Enable When", "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression");
|
||||
}
|
||||
for (Extension e : i.getExtensionsByUrl("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression")) {
|
||||
addExpression(p, e.getValueExpression(), "Calculated Value", "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression");
|
||||
}
|
||||
for (Extension e : i.getExtensionsByUrl("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-candidateExpression")) {
|
||||
addExpression(p, e.getValueExpression(), "Candidates", "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-candidateExpression");
|
||||
}
|
||||
}
|
||||
|
||||
for (QuestionnaireItemComponent c : i.getItem()) {
|
||||
hasExt = renderLogicItem(gen, r.getSubRows(), q, c) || hasExt;
|
||||
}
|
||||
return hasExt;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public boolean renderForm(XhtmlNode x, Questionnaire q) throws UnsupportedEncodingException, IOException {
|
||||
boolean hasExt = false;
|
||||
XhtmlNode d = x.div();
|
||||
|
@ -231,7 +353,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
}
|
||||
int i = 1;
|
||||
for (QuestionnaireItemComponent c : q.getItem()) {
|
||||
hasExt = renderFormItem(d, q, c, hasPrefix ? null : Integer.toString(i), true) || hasExt;
|
||||
hasExt = renderFormItem(d, q, c, hasPrefix ? null : Integer.toString(i), 0) || hasExt;
|
||||
i++;
|
||||
}
|
||||
return hasExt;
|
||||
|
@ -249,20 +371,25 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
return false;
|
||||
}
|
||||
|
||||
private boolean renderFormItem(XhtmlNode x, Questionnaire q, QuestionnaireItemComponent i, String pfx, boolean root) {
|
||||
private boolean renderFormItem(XhtmlNode x, Questionnaire q, QuestionnaireItemComponent i, String pfx, int indent) throws IOException {
|
||||
boolean hasExt = false;
|
||||
XhtmlNode d = x.div();
|
||||
if (!root) {
|
||||
d.style("margin-left: 10px");
|
||||
XhtmlNode d = x.div().style("width: "+Integer.toString(900-indent*10)+"px; border-top: 1px #eeeeee solid");
|
||||
if (indent > 0) {
|
||||
d.style("margin-left: "+Integer.toString(10*indent)+"px");
|
||||
}
|
||||
XhtmlNode display = d.div().style("display: inline-block; width: "+Integer.toString(500-indent*10)+"px");
|
||||
XhtmlNode details = d.div().style("border: 1px #ccccff solid; padding: 2px; display: inline-block; background-color: #fefce7; width: 380px");
|
||||
XhtmlNode p = display.para();
|
||||
if (i.getType() == QuestionnaireItemType.GROUP) {
|
||||
p = p.b();
|
||||
}
|
||||
XhtmlNode p = d.para();
|
||||
if (i.hasPrefix()) {
|
||||
p.tx(i.getPrefix());
|
||||
p.tx(": ");
|
||||
}
|
||||
p.span(null, "linkId: "+i.getLinkId()).tx(i.getText());
|
||||
if (i.getRequired()) {
|
||||
p.span("color: red", "Mandatory").tx(" *");
|
||||
p.span("color: red", "Mandatory").tx("*");
|
||||
}
|
||||
|
||||
XhtmlNode input = null;
|
||||
|
@ -296,6 +423,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
case DISPLAY:
|
||||
break;
|
||||
case GROUP:
|
||||
|
||||
break;
|
||||
case INTEGER:
|
||||
p.tx(" ");
|
||||
|
@ -325,17 +453,142 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
if (input != null) {
|
||||
if (i.getReadOnly()) {
|
||||
input.attribute("readonly", "1");
|
||||
input.style("background-color: #eeeeee");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// if (i.hasExtension("http://hl7.org/fhir/StructureDefinition/questionnaire-choiceOrientation")) {
|
||||
// String code = ToolingExtensions.readStringExtension(i, "http://hl7.org/fhir/StructureDefinition/questionnaire-choiceOrientation");
|
||||
// flags.addPiece(gen.new Piece("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod", null, "Orientation: "+code).addHtml(new XhtmlNode(NodeType.Element, "img").attribute("src", Utilities.path(context.getDestDir(), "icon-qi-"+code+".png"))));
|
||||
//}
|
||||
|
||||
|
||||
XhtmlNode ul = details.ul();
|
||||
boolean hasFlag = false;
|
||||
XhtmlNode flags = item(ul, "Flags");
|
||||
item(ul, "linkId", i.getLinkId());
|
||||
|
||||
if (ToolingExtensions.readBoolExtension(i, "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-isSubject")) {
|
||||
hasFlag = true;
|
||||
flags.ah("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-isSubject", "Can change the subject of the questionnaire").img(Utilities.path(context.getDestDir(), "icon-qi-subject.png"));
|
||||
}
|
||||
if (ToolingExtensions.readBoolExtension(i, "http://hl7.org/fhir/StructureDefinition/questionnaire-hidden")) {
|
||||
hasFlag = true;
|
||||
flags.ah(Utilities.pathURL(context.getSpecificationLink(), "extension-questionnaire-hidden.html"), "Is a hidden item").img(Utilities.path(context.getDestDir(), "icon-qi-hidden.png"));
|
||||
d.style("background-color: #eeeeee");
|
||||
}
|
||||
if (ToolingExtensions.readBoolExtension(i, "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-optionalDisplay")) {
|
||||
hasFlag = true;
|
||||
flags.ah("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-optionalDisplay", "Is optional to display").img(Utilities.path(context.getDestDir(), "icon-qi-optional.png"));
|
||||
}
|
||||
if (i.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod")) {
|
||||
hasFlag = true;
|
||||
flags.ah("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod", "Is linked to an observation").img(Utilities.path(context.getDestDir(), "icon-qi-observation.png"));
|
||||
}
|
||||
if (i.hasExtension("http://hl7.org/fhir/StructureDefinition/questionnaire-displayCategory")) {
|
||||
CodeableConcept cc = i.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/questionnaire-displayCategory").getValueCodeableConcept();
|
||||
String code = cc.getCode("http://hl7.org/fhir/questionnaire-display-category");
|
||||
hasFlag = true;
|
||||
flags.ah("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-displayCategory", "Category: "+code).img(Utilities.path(context.getDestDir(), "icon-qi-"+code+".png"));
|
||||
}
|
||||
|
||||
if (i.hasMaxLength()) {
|
||||
item(ul, "Max Length", Integer.toString(i.getMaxLength()));
|
||||
}
|
||||
if (i.hasDefinition()) {
|
||||
item(ul, "Definition", i.getDefinition());
|
||||
}
|
||||
if (i.hasEnableWhen()) {
|
||||
item(ul, "Enable When", "todo");
|
||||
}
|
||||
if (i.hasAnswerValueSet()) {
|
||||
XhtmlNode ans = item(ul, "Answers");
|
||||
if (i.getAnswerValueSet().startsWith("#")) {
|
||||
ValueSet vs = (ValueSet) q.getContained(i.getAnswerValueSet().substring(1));
|
||||
if (vs == null) {
|
||||
ans.tx(i.getAnswerValueSet());
|
||||
} else {
|
||||
ans.ah("todo").tx(vs.present());
|
||||
}
|
||||
} else {
|
||||
ValueSet vs = context.getWorker().fetchResource(ValueSet.class, i.getAnswerValueSet());
|
||||
if (vs == null || !vs.hasUserData("path")) {
|
||||
ans.tx(i.getAnswerValueSet());
|
||||
} else {
|
||||
ans.ah(vs.getUserString("path")).tx(vs.present());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i.hasAnswerOption()) {
|
||||
item(ul, "Answers", Integer.toString(i.getAnswerOption().size())+" "+Utilities.pluralize("option", i.getAnswerOption().size()), context.getDefinitionsTarget()+"#"+i.getLinkId());
|
||||
}
|
||||
if (i.hasInitial()) {
|
||||
XhtmlNode vi = item(ul, "Initial Values");
|
||||
boolean first = true;
|
||||
for (QuestionnaireItemInitialComponent v : i.getInitial()) {
|
||||
if (first) first = false; else vi.tx(", ");
|
||||
if (v.getValue().isPrimitive()) {
|
||||
vi.tx(v.getValue().primitiveValue());
|
||||
} else {
|
||||
vi.tx("{todo}");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasFlag) {
|
||||
ul.remove(flags);
|
||||
}
|
||||
// if (i.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression") || i.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-itemContext") || i.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression") || i.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-contextExpression") || i.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-candidateExpression") || i.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression")) {
|
||||
// if (!defn.getPieces().isEmpty()) defn.addPiece(gen.new Piece("br"));
|
||||
// defn.getPieces().add(gen.new Piece(null, "Expressions: ", null));
|
||||
// Piece p = gen.new Piece("ul");
|
||||
// defn.getPieces().add(p);
|
||||
// for (Extension e : i.getExtensionsByUrl("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression")) {
|
||||
// addExpression(p, e.getValueExpression(), "Initial Value", "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression");
|
||||
// }
|
||||
// for (Extension e : i.getExtensionsByUrl("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-contextExpression")) {
|
||||
// addExpression(p, e.getValueExpression(), "Context", "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-contextExpression");
|
||||
// }
|
||||
// for (Extension e : i.getExtensionsByUrl("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-itemContext")) {
|
||||
// addExpression(p, e.getValueExpression(), "Item Context", "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-itemContext");
|
||||
// }
|
||||
// for (Extension e : i.getExtensionsByUrl("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression")) {
|
||||
// addExpression(p, e.getValueExpression(), "Enable When", "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression");
|
||||
// }
|
||||
// for (Extension e : i.getExtensionsByUrl("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression")) {
|
||||
// addExpression(p, e.getValueExpression(), "Calculated Value", "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression");
|
||||
// }
|
||||
// for (Extension e : i.getExtensionsByUrl("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-candidateExpression")) {
|
||||
// addExpression(p, e.getValueExpression(), "Candidates", "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-candidateExpression");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
|
||||
int t = 1;
|
||||
for (QuestionnaireItemComponent c : i.getItem()) {
|
||||
hasExt = renderFormItem(d, q, c, pfx == null ? null : pfx+"."+Integer.toString(t), false) || hasExt;
|
||||
hasExt = renderFormItem(x, q, c, pfx == null ? null : pfx+"."+Integer.toString(t), indent+1) || hasExt;
|
||||
t++;
|
||||
}
|
||||
return hasExt;
|
||||
}
|
||||
|
||||
private void item(XhtmlNode ul, String name, String value, String valueLink) {
|
||||
if (!Utilities.noString(value)) {
|
||||
ul.li().style("font-size: 10px").ah(valueLink).tx(name+": "+value);
|
||||
}
|
||||
}
|
||||
|
||||
private void item(XhtmlNode ul, String name, String value) {
|
||||
if (!Utilities.noString(value)) {
|
||||
ul.li().style("font-size: 10px").tx(name+": "+value);
|
||||
}
|
||||
}
|
||||
private XhtmlNode item(XhtmlNode ul, String name) {
|
||||
XhtmlNode li = ul.li();
|
||||
li.style("font-size: 10px").tx(name+": ");
|
||||
return li;
|
||||
}
|
||||
|
||||
|
||||
private void listOptions(Questionnaire q, QuestionnaireItemComponent i, XhtmlNode select) {
|
||||
if (i.hasAnswerValueSet()) {
|
||||
ValueSet vs = null;
|
||||
|
@ -362,12 +615,207 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
|
|||
select.option("a", "??", false);
|
||||
}
|
||||
|
||||
public String display(DomainResource dr) throws UnsupportedEncodingException, IOException {
|
||||
public String display(Resource dr) throws UnsupportedEncodingException, IOException {
|
||||
return display((Questionnaire) dr);
|
||||
}
|
||||
|
||||
public String display(Questionnaire q) throws UnsupportedEncodingException, IOException {
|
||||
return "Questionnaire "+q.present();
|
||||
}
|
||||
|
||||
private boolean renderLinks(XhtmlNode x, Questionnaire q) {
|
||||
x.para().tx("Try this questionnaire out:");
|
||||
XhtmlNode ul = x.ul();
|
||||
ul.li().ah("http://todo.nlm.gov/path?mode=ig&src="+Utilities.pathURL(context.getSelfLink(), "package.tgz")+"&q="+q.getId()+".json").tx("NLM Forms Library");
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean renderDefns(XhtmlNode x, Questionnaire q) throws IOException {
|
||||
XhtmlNode tbl = x.table("dict");
|
||||
boolean ext = false;
|
||||
for (QuestionnaireItemComponent qi : q.getItem()) {
|
||||
ext = renderDefinition(tbl, q, qi, new ArrayList<>()) || ext;
|
||||
}
|
||||
return ext;
|
||||
}
|
||||
|
||||
private boolean renderDefinition(XhtmlNode tbl, Questionnaire q, QuestionnaireItemComponent qi, List<QuestionnaireItemComponent> parents) throws IOException {
|
||||
boolean ext = false;
|
||||
XhtmlNode td = tbl.tr().td("structure").colspan("2").span(null, null).attribute("class", "self-link-parent");
|
||||
td.an(qi.getLinkId());
|
||||
for (QuestionnaireItemComponent p : parents) {
|
||||
td.ah("#"+p.getLinkId()).img(Utilities.path(context.getDestDir(), "icon_q_item.png"));
|
||||
td.tx(" > ");
|
||||
}
|
||||
td.img(Utilities.path(context.getDestDir(), "icon_q_item.png"));
|
||||
td.tx(" Item ");
|
||||
td.b().tx(qi.getLinkId());
|
||||
|
||||
// general information
|
||||
defn(tbl, "Link Id", qi.getLinkId());
|
||||
defn(tbl, "Prefix", qi.getPrefix());
|
||||
defn(tbl, "Text", qi.getText());
|
||||
defn(tbl, "Type", qi.getType().getDisplay());
|
||||
defn(tbl, "Required", qi.getRequired(), true);
|
||||
defn(tbl, "Repeats", qi.getRepeats(), true);
|
||||
defn(tbl, "Read Only", qi.getReadOnly(), false);
|
||||
if (ToolingExtensions.readBoolExtension(qi, "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-isSubject")) {
|
||||
defn(tbl, "Subject", "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-isSubject", "This element changes who the subject of the question is", null);
|
||||
}
|
||||
|
||||
// content control
|
||||
defn(tbl, "Max Length", qi.getMaxLength());
|
||||
if (qi.hasAnswerValueSet()) {
|
||||
defn(tbl, "Value Set", qi.getDefinition(), context.getWorker().fetchResource(ValueSet.class, qi.getAnswerValueSet()));
|
||||
}
|
||||
if (qi.hasAnswerOption()) {
|
||||
XhtmlNode tr = tbl.tr();
|
||||
tr.td().tx("Allowed Answers");
|
||||
XhtmlNode ul = tr.td().ul();
|
||||
for (QuestionnaireItemAnswerOptionComponent ans : qi.getAnswerOption()) {
|
||||
XhtmlNode li = ul.li();
|
||||
render(li, ans.getValue());
|
||||
if (ans.getInitialSelected()) {
|
||||
li.tx(" (initially selected)");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (qi.hasInitial()) {
|
||||
XhtmlNode tr = tbl.tr();
|
||||
tr.td().tx(Utilities.pluralize("Initial Answer", qi.getInitial().size()));
|
||||
if (qi.getInitial().size() == 1) {
|
||||
render(tr.td(), qi.getInitialFirstRep().getValue());
|
||||
} else {
|
||||
XhtmlNode ul = tr.td().ul();
|
||||
for (QuestionnaireItemInitialComponent ans : qi.getInitial()) {
|
||||
XhtmlNode li = ul.li();
|
||||
render(li, ans.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// appearance
|
||||
if (qi.hasExtension("http://hl7.org/fhir/StructureDefinition/questionnaire-displayCategory")) {
|
||||
XhtmlNode tr = tbl.tr();
|
||||
tr.td().ah("http://hl7.org/fhir/StructureDefinition/questionnaire-displayCategory").tx("Display Category");
|
||||
render(tr.td(), qi.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/questionnaire-displayCategory").getValue());
|
||||
}
|
||||
if (ToolingExtensions.readBoolExtension(qi, "http://hl7.org/fhir/StructureDefinition/questionnaire-hidden")) {
|
||||
defn(tbl, "Hidden Item", "http://hl7.org/fhir/StructureDefinition/questionnaire-displayCategory", "This item is a hidden question", null);
|
||||
}
|
||||
if (ToolingExtensions.readBoolExtension(qi, "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-optionalDisplay")) {
|
||||
defn(tbl, "Hidden Item", "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-optionalDisplay", "This item is optional to display", null);
|
||||
}
|
||||
|
||||
// formal definitions
|
||||
if (qi.hasDefinition()) {
|
||||
defn(tbl, "Definition", qi.getDefinition(), context.getWorker().fetchResource(Resource.class, qi.getDefinition()));
|
||||
}
|
||||
if (qi.hasCode()) {
|
||||
XhtmlNode tr = tbl.tr();
|
||||
tr.td().tx(Utilities.pluralize("Code", qi.getCode().size()));
|
||||
XhtmlNode ul = tr.td().ul();
|
||||
for (Coding c : qi.getCode()) {
|
||||
renderCoding(ul.li(), c);
|
||||
}
|
||||
}
|
||||
if (qi.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod")) {
|
||||
XhtmlNode tr = tbl.tr();
|
||||
tr.td().ah("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod").tx("Observation Link Period");
|
||||
render(tr.td(), qi.getExtensionByUrl("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod").getValue());
|
||||
}
|
||||
|
||||
// dynamic management
|
||||
if (qi.hasEnableWhen()) {
|
||||
XhtmlNode tr = tbl.tr();
|
||||
tr.td().tx("Enable When");
|
||||
td = tr.td();
|
||||
if (qi.getEnableWhen().size() == 1) {
|
||||
renderEnableWhen(td, qi.getEnableWhen().get(0));
|
||||
} else {
|
||||
td.tx(qi.getEnableBehavior().getDisplay()+" are true:");
|
||||
XhtmlNode ul = td.ul();
|
||||
for (QuestionnaireItemEnableWhenComponent ew : qi.getEnableWhen()) {
|
||||
renderEnableWhen(ul.li(), ew);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// other stuff
|
||||
|
||||
|
||||
|
||||
List<QuestionnaireItemComponent> curr = new ArrayList<>();
|
||||
curr.addAll(parents);
|
||||
curr.add(qi);
|
||||
for (QuestionnaireItemComponent qic : qi.getItem()) {
|
||||
ext = renderDefinition(tbl, q, qic, curr) || ext;
|
||||
}
|
||||
return ext;
|
||||
}
|
||||
|
||||
private void defn(XhtmlNode tbl, String name, String url, Resource res) throws UnsupportedEncodingException, IOException {
|
||||
if (res != null && res.hasUserData("path")) {
|
||||
defn(tbl, "Definition", RendererFactory.factory(res, context).display(res), res.getUserString("path"));
|
||||
} else if (Utilities.isAbsoluteUrl(url)) {
|
||||
defn(tbl, "Definition", url, url);
|
||||
} {
|
||||
defn(tbl, "Definition", url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void renderEnableWhen(XhtmlNode x, QuestionnaireItemEnableWhenComponent ew) {
|
||||
x.ah("#"+ew.getQuestion()).tx(ew.getQuestion());
|
||||
x.tx(" ");
|
||||
x.tx(ew.getOperator().toCode());
|
||||
x.tx(" ");
|
||||
x.tx(display(ew.getAnswer()));
|
||||
}
|
||||
|
||||
private void defn(XhtmlNode tbl, String name, int value) {
|
||||
if (value > 0) {
|
||||
XhtmlNode tr = tbl.tr();
|
||||
tr.td().tx(name);
|
||||
tr.td().tx(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void defn(XhtmlNode tbl, String name, String value) {
|
||||
if (!Utilities.noString(value)) {
|
||||
XhtmlNode tr = tbl.tr();
|
||||
tr.td().tx(name);
|
||||
tr.td().tx(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void defn(XhtmlNode tbl, String name, String value, String url) {
|
||||
if (!Utilities.noString(value)) {
|
||||
XhtmlNode tr = tbl.tr();
|
||||
tr.td().tx(name);
|
||||
tr.td().ah(url).tx(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void defn(XhtmlNode tbl, String name, String nurl, String value, String url) {
|
||||
if (!Utilities.noString(value)) {
|
||||
XhtmlNode tr = tbl.tr();
|
||||
tr.td().ah(nurl).tx(name);
|
||||
if (url != null) {
|
||||
tr.td().ah(url).tx(value);
|
||||
} else {
|
||||
tr.td().tx(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void defn(XhtmlNode tbl, String name, boolean value, boolean ifFalse) {
|
||||
if (ifFalse || value) {
|
||||
XhtmlNode tr = tbl.tr();
|
||||
tr.td().tx(name);
|
||||
tr.td().tx(Boolean.toString(value));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -74,21 +74,23 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
assert r.getContext() == context;
|
||||
XhtmlNode x = new XhtmlNode(NodeType.Element, "div");
|
||||
boolean hasExtensions = render(x, r);
|
||||
r.injectNarrative(x, hasExtensions ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
|
||||
if (r.hasNarrative()) {
|
||||
r.injectNarrative(x, hasExtensions ? NarrativeStatus.EXTENSIONS : NarrativeStatus.GENERATED);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
public abstract boolean render(XhtmlNode x, DomainResource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome;
|
||||
|
||||
public boolean render(XhtmlNode x, ResourceWrapper r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
|
||||
throw new NotImplementedException("This is not implemented yet for resources of type "+r.getName());
|
||||
throw new NotImplementedException("Rendering using the wrapper is not implemented yet for resources of type "+r.getName());
|
||||
}
|
||||
|
||||
public void describe(XhtmlNode x, DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
x.tx(display(r));
|
||||
}
|
||||
|
||||
public abstract String display(DomainResource r) throws UnsupportedEncodingException, IOException;
|
||||
public abstract String display(Resource r) throws UnsupportedEncodingException, IOException;
|
||||
|
||||
public static void inject(DomainResource r, XhtmlNode x, NarrativeStatus status) {
|
||||
if (!x.hasAttribute("xmlns"))
|
||||
|
@ -104,7 +106,7 @@ public abstract class ResourceRenderer extends DataRenderer {
|
|||
r.getText().setStatus(status);
|
||||
} else {
|
||||
XhtmlNode n = r.getText().getDiv();
|
||||
n.hr();
|
||||
n.clear();
|
||||
n.getChildNodes().addAll(x.getChildNodes());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.io.UnsupportedEncodingException;
|
|||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||
|
@ -26,7 +27,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
|||
}
|
||||
|
||||
public boolean render(XhtmlNode x, StructureDefinition sd) throws FHIRFormatError, DefinitionException, IOException {
|
||||
x.getChildNodes().add(context.getProfileUtilities().generateTable(context.getDefinitionsTarget(), sd, true, context.getDestDir(), false, sd.getId(), false, context.getPrefix(), "", false, false, null, false));
|
||||
x.getChildNodes().add(context.getProfileUtilities().generateTable(context.getDefinitionsTarget(), sd, true, context.getDestDir(), false, sd.getId(), false, context.getSpecificationLink(), "", false, false, null, false));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -39,7 +40,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String display(DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
public String display(Resource r) throws UnsupportedEncodingException, IOException {
|
||||
return ((StructureDefinition) r).present();
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ public abstract class TerminologyRenderer extends ResourceRenderer {
|
|||
super(context, rcontext);
|
||||
}
|
||||
|
||||
public String display(DomainResource r) throws UnsupportedEncodingException, IOException {
|
||||
public String display(Resource r) throws UnsupportedEncodingException, IOException {
|
||||
return ((CanonicalResource) r).present();
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ public abstract class TerminologyRenderer extends ResourceRenderer {
|
|||
for (UsedConceptMap m : maps) {
|
||||
XhtmlNode td = tr.td();
|
||||
XhtmlNode b = td.b();
|
||||
XhtmlNode a = b.ah(getContext().getPrefix()+m.getLink());
|
||||
XhtmlNode a = b.ah(getContext().getSpecificationLink()+m.getLink());
|
||||
a.addText(m.getDetails().getName());
|
||||
if (m.getDetails().isDoDescription() && m.getMap().hasDescription())
|
||||
addMarkdown(td, m.getMap().getDescription());
|
||||
|
@ -155,19 +155,22 @@ public abstract class TerminologyRenderer extends ResourceRenderer {
|
|||
ref = (String) cs.getUserData("filename");
|
||||
else
|
||||
addHtml = false;
|
||||
if (Utilities.noString(ref))
|
||||
if (Utilities.noString(ref)) {
|
||||
ref = (String) cs.getUserData("path");
|
||||
if (ref != null) {
|
||||
addHtml = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
String spec = getSpecialReference(inc.getSystem());
|
||||
if (spec != null) {
|
||||
XhtmlNode a = li.ah(spec);
|
||||
a.code(inc.getSystem());
|
||||
} else if (cs != null && ref != null) {
|
||||
if (!Utilities.noString(getContext().getPrefix()) && ref.startsWith("http://hl7.org/fhir/"))
|
||||
ref = ref.substring(20)+"/index.html";
|
||||
else if (addHtml && !ref.contains(".html"))
|
||||
if (addHtml && !ref.contains(".html"))
|
||||
ref = ref + ".html";
|
||||
XhtmlNode a = li.ah(getContext().getPrefix()+ref.replace("\\", "/"));
|
||||
ref = context.fixReference(ref);
|
||||
XhtmlNode a = li.ah(ref.replace("\\", "/"));
|
||||
a.code(inc.getSystem());
|
||||
} else {
|
||||
li.code(inc.getSystem());
|
||||
|
@ -260,14 +263,14 @@ public abstract class TerminologyRenderer extends ResourceRenderer {
|
|||
if (vs != null) {
|
||||
String ref = (String) vs.getUserData("path");
|
||||
|
||||
ref = adjustForPath(ref);
|
||||
ref = context.fixReference(ref);
|
||||
XhtmlNode a = li.ah(ref == null ? "?ngen-11?" : ref.replace("\\", "/"));
|
||||
a.addText(value);
|
||||
} else {
|
||||
CodeSystem cs = getContext().getWorker().fetchCodeSystem(value);
|
||||
if (cs != null) {
|
||||
String ref = (String) cs.getUserData("path");
|
||||
ref = adjustForPath(ref);
|
||||
ref = context.fixReference(ref);
|
||||
XhtmlNode a = li.ah(ref == null ? "?ngen-12?" : ref.replace("\\", "/"));
|
||||
a.addText(value);
|
||||
} else if (value.equals("http://snomed.info/sct") || value.equals("http://snomed.info/id")) {
|
||||
|
@ -282,13 +285,6 @@ public abstract class TerminologyRenderer extends ResourceRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
private String adjustForPath(String ref) {
|
||||
if (getContext().getPrefix() == null)
|
||||
return ref;
|
||||
else
|
||||
return getContext().getPrefix()+ref;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected String getDisplayForConcept(String system, String value) {
|
||||
|
|
|
@ -207,7 +207,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
if (ref == null)
|
||||
p.code(vs.getExpansion().getContains().get(0).getSystem());
|
||||
else
|
||||
p.ah(getContext().getPrefix()+ref).code(vs.getExpansion().getContains().get(0).getSystem());
|
||||
p.ah(context.fixReference(ref)).code(vs.getExpansion().getContains().get(0).getSystem());
|
||||
}
|
||||
XhtmlNode t = x.table( "codes");
|
||||
XhtmlNode tr = t.tr();
|
||||
|
@ -638,7 +638,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
} else
|
||||
td.addText(code);
|
||||
} else {
|
||||
String href = getContext().getPrefix()+getCsRef(e);
|
||||
String href = context.fixReference(getCsRef(e));
|
||||
if (href.contains("#"))
|
||||
href = href + "-"+Utilities.nmtokenize(code);
|
||||
else
|
||||
|
@ -662,9 +662,9 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
String cslink = getCsRef(cs);
|
||||
XhtmlNode a = null;
|
||||
if (cslink != null)
|
||||
a = td.ah(getContext().getPrefix()+cslink+"#"+cs.getId()+"-"+code);
|
||||
a = td.ah(getContext().getSpecificationLink()+cslink+"#"+cs.getId()+"-"+code);
|
||||
else
|
||||
a = td.ah(getContext().getPrefix()+vslink+"#"+code);
|
||||
a = td.ah(getContext().getSpecificationLink()+vslink+"#"+code);
|
||||
a.addText(code);
|
||||
}
|
||||
|
||||
|
@ -796,7 +796,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
} else {
|
||||
li.tx(f.getProperty()+" "+describe(f.getOp())+" ");
|
||||
if (e != null && codeExistsInValueSet(e, f.getValue())) {
|
||||
String href = getContext().getPrefix()+getCsRef(e);
|
||||
String href = getContext().fixReference(getCsRef(e));
|
||||
if (href.contains("#"))
|
||||
href = href + "-"+Utilities.nmtokenize(f.getValue());
|
||||
else
|
||||
|
|
|
@ -29,6 +29,7 @@ public class BaseWrappers {
|
|||
public int getMaxCardinality();
|
||||
public StructureDefinition getStructure();
|
||||
public BaseWrapper value();
|
||||
public ResourceWrapper getAsResource();
|
||||
}
|
||||
|
||||
public interface WrapperBase extends RendererWrapper {
|
||||
|
@ -42,11 +43,13 @@ public class BaseWrappers {
|
|||
public List<ResourceWrapper> getContained();
|
||||
public String getId();
|
||||
public XhtmlNode getNarrative() throws FHIRFormatError, IOException, FHIRException;
|
||||
public Base getBase();
|
||||
public String getName();
|
||||
public void describe(XhtmlNode x) throws UnsupportedEncodingException, IOException;
|
||||
public void injectNarrative(XhtmlNode x, NarrativeStatus status) throws IOException;
|
||||
public BaseWrapper root();
|
||||
public StructureDefinition getDefinition();
|
||||
public boolean hasNarrative();
|
||||
}
|
||||
|
||||
public interface BaseWrapper extends WrapperBase {
|
||||
|
|
|
@ -178,6 +178,11 @@ public class DOMWrappers {
|
|||
return getValues().get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceWrapper getAsResource() {
|
||||
throw new Error("Not implemented yet");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ResourceWrapperElement extends WrapperBaseImpl implements ResourceWrapper {
|
||||
|
@ -307,6 +312,23 @@ public class DOMWrappers {
|
|||
public StructureDefinition getDefinition() {
|
||||
return definition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base getBase() {
|
||||
throw new Error("Not Implemented yet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNarrative() {
|
||||
StructureDefinition sd = definition;
|
||||
while (sd != null) {
|
||||
if ("DomainResource".equals(sd.getType())) {
|
||||
return true;
|
||||
}
|
||||
sd = context.getWorker().fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -96,6 +96,11 @@ public class DirectWrappers {
|
|||
public String toString() {
|
||||
return "#."+wrapped.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceWrapper getAsResource() {
|
||||
throw new Error("Not implemented yet");
|
||||
}
|
||||
}
|
||||
|
||||
public static class BaseWrapperDirect extends WrapperBaseImpl implements BaseWrapper {
|
||||
|
@ -214,6 +219,24 @@ public class DirectWrappers {
|
|||
public StructureDefinition getDefinition() {
|
||||
return context.getWorker().fetchTypeDefinition(wrapped.fhirType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base getBase() {
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNarrative() {
|
||||
StructureDefinition sd = context.getWorker().fetchTypeDefinition(wrapped.fhirType());
|
||||
while (sd != null) {
|
||||
if ("DomainResource".equals(sd.getType())) {
|
||||
return true;
|
||||
}
|
||||
sd = context.getWorker().fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -48,8 +48,9 @@ public class ElementWrappers {
|
|||
if (type == null || type.equals("Resource") || type.equals("BackboneElement") || type.equals("Element"))
|
||||
return null;
|
||||
|
||||
if (element.hasElementProperty())
|
||||
return null;
|
||||
if (element.hasElementProperty()) {
|
||||
return element;
|
||||
}
|
||||
ByteArrayOutputStream xml = new ByteArrayOutputStream();
|
||||
try {
|
||||
new XmlParser(context.getWorker()).compose(element, xml, OutputStyle.PRETTY, null);
|
||||
|
@ -57,7 +58,7 @@ public class ElementWrappers {
|
|||
throw new FHIRException(e.getMessage(), e);
|
||||
}
|
||||
if (context.getParser() == null) {
|
||||
System.out.println("huh?");
|
||||
System.out.println("Noe version specific parser provided");
|
||||
}
|
||||
return context.getParser().parseType(xml.toString(), type);
|
||||
}
|
||||
|
@ -214,6 +215,23 @@ public class ElementWrappers {
|
|||
public StructureDefinition getDefinition() {
|
||||
return definition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Base getBase() {
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNarrative() {
|
||||
StructureDefinition sd = definition;
|
||||
while (sd != null) {
|
||||
if ("DomainResource".equals(sd.getType())) {
|
||||
return true;
|
||||
}
|
||||
sd = context.getWorker().fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PropertyWrapperMetaElement extends RendererWrapperImpl implements PropertyWrapper {
|
||||
|
@ -282,6 +300,11 @@ public class ElementWrappers {
|
|||
return getValues().get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceWrapper getAsResource() {
|
||||
return new ElementWrappers.ResourceWrapperMetaElement(context, values.get(0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -16,6 +16,7 @@ import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
|||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor.Dialect;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||
|
||||
public class RenderingContext {
|
||||
|
@ -33,22 +34,53 @@ public class RenderingContext {
|
|||
RESOURCE, IG
|
||||
}
|
||||
|
||||
protected IWorkerContext worker;
|
||||
protected MarkDownProcessor markdown;
|
||||
protected ResourceRendererMode mode;
|
||||
|
||||
public enum QuestionnaireRendererMode {
|
||||
/**
|
||||
* A visual presentation of the questionnaire, with a set of property panes that can be toggled on and off.
|
||||
* Note that this is not the same as how the questionnaire would like on a form filler, since all dynamic behavior is ignored
|
||||
*/
|
||||
FORM,
|
||||
|
||||
/**
|
||||
* a structured tree that presents the content of the questionnaire in a logical fashion
|
||||
*/
|
||||
TREE,
|
||||
|
||||
/**
|
||||
* A structured tree that presents the enableWhen, terminology and expression bindings for the questionnaire
|
||||
*/
|
||||
LOGIC,
|
||||
|
||||
/**
|
||||
* A presentation that lists all the items, with full details about them
|
||||
*/
|
||||
DEFNS,
|
||||
|
||||
/**
|
||||
* Rendered links to various openly available Form Filler applications that know how to render a questionnaire published in a package
|
||||
*/
|
||||
LINKS
|
||||
}
|
||||
|
||||
private IWorkerContext worker;
|
||||
private MarkDownProcessor markdown;
|
||||
private ResourceRendererMode mode;
|
||||
private IReferenceResolver resolver;
|
||||
private ILiquidTemplateProvider templateProvider;
|
||||
private IEvaluationContext services;
|
||||
private ITypeParser parser;
|
||||
|
||||
protected String lang;
|
||||
protected String prefix;
|
||||
private String lang;
|
||||
private String localPrefix; // relative link within local context
|
||||
private String specificationLink;
|
||||
private String selfLink; // absolute link to where the content is to be found (only used in a few circumstances when making external references to tools)
|
||||
private int headerLevelContext;
|
||||
private boolean canonicalUrlsAsLinks;
|
||||
private boolean pretty;
|
||||
private boolean header;
|
||||
|
||||
protected ValidationOptions terminologyServiceOptions;
|
||||
private ValidationOptions terminologyServiceOptions;
|
||||
private boolean noSlowLookup;
|
||||
private String tooCostlyNoteEmpty;
|
||||
private String tooCostlyNoteNotEmpty;
|
||||
|
@ -56,26 +88,28 @@ public class RenderingContext {
|
|||
private String tooCostlyNoteNotEmptyDependent;
|
||||
private List<String> codeSystemPropList = new ArrayList<>();
|
||||
|
||||
protected ProfileUtilities profileUtilities;
|
||||
private ProfileUtilities profileUtilities;
|
||||
private String definitionsTarget;
|
||||
private String destDir;
|
||||
private boolean inlineGraphics;
|
||||
|
||||
|
||||
private QuestionnaireRendererMode questionnaireMode = QuestionnaireRendererMode.FORM;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param context - access to all related resources that might be needed
|
||||
* @param markdown - appropriate markdown processing engine
|
||||
* @param terminologyServiceOptions - options to use when looking up codes
|
||||
* @param prefix - path to FHIR specification
|
||||
* @param specLink - path to FHIR specification
|
||||
* @param lang - langauage to render in
|
||||
*/
|
||||
public RenderingContext(IWorkerContext worker, MarkDownProcessor markdown, ValidationOptions terminologyServiceOptions, String prefix, String lang, ResourceRendererMode mode) {
|
||||
public RenderingContext(IWorkerContext worker, MarkDownProcessor markdown, ValidationOptions terminologyServiceOptions, String specLink, String localPrefix, String lang, ResourceRendererMode mode) {
|
||||
super();
|
||||
this.worker = worker;
|
||||
this.markdown = markdown;
|
||||
this.lang = lang;
|
||||
this.prefix = prefix;
|
||||
this.specificationLink = specLink;
|
||||
this.localPrefix = localPrefix;
|
||||
this.mode = mode;
|
||||
this.terminologyServiceOptions = terminologyServiceOptions;
|
||||
profileUtilities = new ProfileUtilities(worker, null, null);
|
||||
|
@ -115,8 +149,12 @@ public class RenderingContext {
|
|||
return lang;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
public String getSpecificationLink() {
|
||||
return specificationLink;
|
||||
}
|
||||
|
||||
public String getLocalPrefix() {
|
||||
return localPrefix;
|
||||
}
|
||||
|
||||
public ValidationOptions getTerminologyServiceOptions() {
|
||||
|
@ -262,7 +300,7 @@ public class RenderingContext {
|
|||
}
|
||||
|
||||
public RenderingContext copy() {
|
||||
RenderingContext res = new RenderingContext(worker, markdown, terminologyServiceOptions, prefix, lang, mode);
|
||||
RenderingContext res = new RenderingContext(worker, markdown, terminologyServiceOptions, specificationLink, localPrefix, lang, mode);
|
||||
|
||||
res.resolver = resolver;
|
||||
res.templateProvider = templateProvider;
|
||||
|
@ -302,6 +340,32 @@ public class RenderingContext {
|
|||
public void setHeader(boolean header) {
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
public QuestionnaireRendererMode getQuestionnaireMode() {
|
||||
return questionnaireMode;
|
||||
}
|
||||
|
||||
public void setQuestionnaireMode(QuestionnaireRendererMode questionnaireMode) {
|
||||
this.questionnaireMode = questionnaireMode;
|
||||
}
|
||||
|
||||
public String getSelfLink() {
|
||||
return selfLink;
|
||||
}
|
||||
|
||||
public void setSelfLink(String selfLink) {
|
||||
this.selfLink = selfLink;
|
||||
}
|
||||
|
||||
public String fixReference(String ref) {
|
||||
if (!Utilities.isAbsoluteUrl(ref)) {
|
||||
return (localPrefix == null ? "" : localPrefix)+ref;
|
||||
}
|
||||
if (ref.startsWith("http://hl7.org/fhir") && !ref.substring(20).contains("/")) {
|
||||
return specificationLink+ref.substring(20);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ import javax.xml.parsers.DocumentBuilder;
|
|||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.fhir.ucum.UcumEssenceService;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.context.SimpleWorkerContext;
|
||||
|
@ -25,6 +24,7 @@ import org.hl7.fhir.utilities.Utilities;
|
|||
import org.hl7.fhir.utilities.VersionUtilities;
|
||||
import org.hl7.fhir.utilities.cache.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.cache.ToolsVersion;
|
||||
import org.hl7.fhir.utilities.tests.BaseTestingUtilities;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
|
@ -67,7 +67,7 @@ import com.google.gson.JsonObject;
|
|||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
public class TestingUtilities {
|
||||
public class TestingUtilities extends BaseTestingUtilities {
|
||||
private static final boolean SHOW_DIFF = true;
|
||||
|
||||
static public Map<String, IWorkerContext> fcontexts;
|
||||
|
@ -97,8 +97,6 @@ public class TestingUtilities {
|
|||
return fcontexts.get(v);
|
||||
}
|
||||
|
||||
static public boolean silent;
|
||||
|
||||
static public String fixedpath;
|
||||
static public String contentpath;
|
||||
|
||||
|
@ -457,74 +455,6 @@ public class TestingUtilities {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static boolean findTestResource(String... paths) throws IOException {
|
||||
if (new File("../../fhir-test-cases").exists() && isTryToLoadFromFileSystem()) {
|
||||
String n = Utilities.path(System.getProperty("user.dir"), "..", "..", "fhir-test-cases", Utilities.path(paths));
|
||||
return new File(n).exists();
|
||||
} else {
|
||||
String classpath = ("/org/hl7/fhir/testcases/" + Utilities.pathURL(paths));
|
||||
try {
|
||||
InputStream inputStream = TestingUtilities.class.getResourceAsStream(classpath);
|
||||
return inputStream != null;
|
||||
} catch (Throwable t) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: JA need to figure out how to detect that we're running in maven
|
||||
private static boolean isTryToLoadFromFileSystem() {
|
||||
return !"true".equals(System.getProperty("dont_load_from_filesystem"));
|
||||
}
|
||||
|
||||
public static String loadTestResource(String... paths) throws IOException {
|
||||
if (new File("../../fhir-test-cases").exists() && isTryToLoadFromFileSystem()) {
|
||||
String n = Utilities.path(System.getProperty("user.dir"), "..", "..", "fhir-test-cases", Utilities.path(paths));
|
||||
// ok, we'll resolve this locally
|
||||
return TextFile.fileToString(new File(n));
|
||||
} else {
|
||||
// resolve from the package
|
||||
String contents;
|
||||
String classpath = ("/org/hl7/fhir/testcases/" + Utilities.pathURL(paths));
|
||||
try (InputStream inputStream = TestingUtilities.class.getResourceAsStream(classpath)) {
|
||||
if (inputStream == null) {
|
||||
throw new IOException("Can't find file on classpath: " + classpath);
|
||||
}
|
||||
contents = IOUtils.toString(inputStream, java.nio.charset.StandardCharsets.UTF_8);
|
||||
}
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
|
||||
public static InputStream loadTestResourceStream(String... paths) throws IOException {
|
||||
if (new File("../../fhir-test-cases").exists() && isTryToLoadFromFileSystem()) {
|
||||
String n = Utilities.path(System.getProperty("user.dir"), "..", "..", "fhir-test-cases", Utilities.path(paths));
|
||||
return new FileInputStream(n);
|
||||
} else {
|
||||
String classpath = ("/org/hl7/fhir/testcases/" + Utilities.pathURL(paths));
|
||||
InputStream s = TestingUtilities.class.getResourceAsStream(classpath);
|
||||
if (s == null) {
|
||||
throw new Error("unable to find resource " + classpath);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] loadTestResourceBytes(String... paths) throws IOException {
|
||||
if (new File("../../fhir-test-cases").exists() && isTryToLoadFromFileSystem()) {
|
||||
String n = Utilities.path(System.getProperty("user.dir"), "..", "..", "fhir-test-cases", Utilities.path(paths));
|
||||
return TextFile.fileToBytes(n);
|
||||
} else {
|
||||
String classpath = ("/org/hl7/fhir/testcases/" + Utilities.pathURL(paths));
|
||||
InputStream s = TestingUtilities.class.getResourceAsStream(classpath);
|
||||
if (s == null) {
|
||||
throw new Error("unable to find resource " + classpath);
|
||||
}
|
||||
return TextFile.streamToBytes(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String tempFile(String folder, String name) throws IOException {
|
||||
String tmp = tempFolder(folder);
|
||||
return Utilities.path(tmp, name);
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
package org.hl7.fhir.r5.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of HL7 nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.PathEngineException;
|
||||
|
@ -55,10 +55,10 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
public interface ILiquidEngineIcludeResolver {
|
||||
public String fetchInclude(LiquidEngine engine, String name);
|
||||
}
|
||||
|
||||
|
||||
private IEvaluationContext externalHostServices;
|
||||
private FHIRPathEngine engine;
|
||||
private ILiquidEngineIcludeResolver includeResolver;
|
||||
private ILiquidEngineIcludeResolver includeResolver;
|
||||
|
||||
private class LiquidEngineContext {
|
||||
private Object externalContext;
|
||||
|
@ -82,7 +82,7 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
engine = new FHIRPathEngine(context);
|
||||
engine.setHostServices(this);
|
||||
}
|
||||
|
||||
|
||||
public ILiquidEngineIcludeResolver getIncludeResolver() {
|
||||
return includeResolver;
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
return new LiquidParser(source).parse(sourceName);
|
||||
}
|
||||
|
||||
public String evaluate(LiquidDocument document, Resource resource, Object appContext) throws FHIRException {
|
||||
public String evaluate(LiquidDocument document, Base resource, Object appContext) throws FHIRException {
|
||||
StringBuilder b = new StringBuilder();
|
||||
LiquidEngineContext ctxt = new LiquidEngineContext(appContext);
|
||||
for (LiquidNode n : document.body) {
|
||||
|
@ -105,9 +105,10 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
}
|
||||
|
||||
private abstract class LiquidNode {
|
||||
protected void closeUp() {}
|
||||
protected void closeUp() {
|
||||
}
|
||||
|
||||
public abstract void evaluate(StringBuilder b, Resource resource, LiquidEngineContext ctxt) throws FHIRException;
|
||||
public abstract void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) throws FHIRException;
|
||||
}
|
||||
|
||||
private class LiquidConstant extends LiquidNode {
|
||||
|
@ -125,7 +126,7 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void evaluate(StringBuilder b, Resource resource, LiquidEngineContext ctxt) {
|
||||
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) {
|
||||
b.append(constant);
|
||||
}
|
||||
}
|
||||
|
@ -135,48 +136,191 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
private ExpressionNode compiled;
|
||||
|
||||
@Override
|
||||
public void evaluate(StringBuilder b, Resource resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||
if (compiled == null)
|
||||
compiled = engine.parse(statement);
|
||||
b.append(engine.evaluateToString(ctxt, resource, resource, resource, compiled));
|
||||
}
|
||||
}
|
||||
|
||||
private class LiquidElsIf extends LiquidNode {
|
||||
private String condition;
|
||||
private ExpressionNode compiled;
|
||||
private List<LiquidNode> body = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||
for (LiquidNode n : body) {
|
||||
n.evaluate(b, resource, ctxt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class LiquidIf extends LiquidNode {
|
||||
private String condition;
|
||||
private ExpressionNode compiled;
|
||||
private List<LiquidNode> thenBody = new ArrayList<>();
|
||||
private List<LiquidElsIf> elseIf = new ArrayList<>();
|
||||
private List<LiquidNode> elseBody = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void evaluate(StringBuilder b, Resource resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||
if (compiled == null)
|
||||
compiled = engine.parse(condition);
|
||||
boolean ok = engine.evaluateToBoolean(ctxt, resource, resource, resource, compiled);
|
||||
List<LiquidNode> list = ok ? thenBody : elseBody;
|
||||
boolean ok = engine.evaluateToBoolean(ctxt, resource, resource, resource, compiled);
|
||||
List<LiquidNode> list = null;
|
||||
if (ok) {
|
||||
list = thenBody;
|
||||
|
||||
} else {
|
||||
list = elseBody;
|
||||
for (LiquidElsIf i : elseIf) {
|
||||
if (i.compiled == null)
|
||||
i.compiled = engine.parse(i.condition);
|
||||
ok = engine.evaluateToBoolean(ctxt, resource, resource, resource, i.compiled);
|
||||
if (ok) {
|
||||
list = i.body;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (LiquidNode n : list) {
|
||||
n.evaluate(b, resource, ctxt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class LiquidLoop extends LiquidNode {
|
||||
private class LiquidContinueExecuted extends FHIRException {
|
||||
private static final long serialVersionUID = 4748737094188943721L;
|
||||
}
|
||||
|
||||
private class LiquidContinue extends LiquidNode {
|
||||
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||
throw new LiquidContinueExecuted();
|
||||
}
|
||||
}
|
||||
|
||||
private class LiquidBreakExecuted extends FHIRException {
|
||||
private static final long serialVersionUID = 6328496371172871082L;
|
||||
}
|
||||
|
||||
private class LiquidBreak extends LiquidNode {
|
||||
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||
throw new LiquidBreakExecuted();
|
||||
}
|
||||
}
|
||||
|
||||
private class LiquidCycle extends LiquidNode {
|
||||
private List<String> list = new ArrayList<>();
|
||||
private int cursor = 0;
|
||||
|
||||
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||
b.append(list.get(cursor));
|
||||
cursor++;
|
||||
if (cursor == list.size()) {
|
||||
cursor = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class LiquidFor extends LiquidNode {
|
||||
private String varName;
|
||||
private String condition;
|
||||
private ExpressionNode compiled;
|
||||
private boolean reversed = false;
|
||||
private int limit = -1;
|
||||
private int offset = -1;
|
||||
private List<LiquidNode> body = new ArrayList<>();
|
||||
private List<LiquidNode> elseBody = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void evaluate(StringBuilder b, Resource resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||
if (compiled == null)
|
||||
compiled = engine.parse(condition);
|
||||
List<Base> list = engine.evaluate(ctxt, resource, resource, resource, compiled);
|
||||
LiquidEngineContext lctxt = new LiquidEngineContext(ctxt);
|
||||
for (Base o : list) {
|
||||
lctxt.vars.put(varName, o);
|
||||
for (LiquidNode n : body) {
|
||||
n.evaluate(b, resource, lctxt);
|
||||
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||
if (compiled == null) {
|
||||
ExpressionNodeWithOffset po = engine.parsePartial(condition, 0);
|
||||
compiled = po.getNode();
|
||||
if (po.getOffset() < condition.length()) {
|
||||
parseModifiers(condition.substring(po.getOffset()));
|
||||
}
|
||||
}
|
||||
List<Base> list = engine.evaluate(ctxt, resource, resource, resource, compiled);
|
||||
LiquidEngineContext lctxt = new LiquidEngineContext(ctxt);
|
||||
if (list.isEmpty()) {
|
||||
for (LiquidNode n : elseBody) {
|
||||
n.evaluate(b, resource, lctxt);
|
||||
}
|
||||
} else {
|
||||
if (reversed) {
|
||||
Collections.reverse(list);
|
||||
}
|
||||
int i = 0;
|
||||
for (Base o : list) {
|
||||
if (offset >= 0 && i < offset) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (limit >= 0 && i == limit) {
|
||||
break;
|
||||
}
|
||||
lctxt.vars.put(varName, o);
|
||||
boolean wantBreak = false;
|
||||
for (LiquidNode n : body) {
|
||||
try {
|
||||
n.evaluate(b, resource, lctxt);
|
||||
} catch (LiquidContinueExecuted e) {
|
||||
break;
|
||||
} catch (LiquidBreakExecuted e) {
|
||||
wantBreak = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (wantBreak) {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseModifiers(String cnt) {
|
||||
String src = cnt;
|
||||
while (!Utilities.noString(cnt)) {
|
||||
if (cnt.startsWith("reversed")) {
|
||||
reversed = true;
|
||||
cnt = cnt.substring(8);
|
||||
} else if (cnt.startsWith("limit")) {
|
||||
cnt = cnt.substring(5).trim();
|
||||
if (!cnt.startsWith(":")) {
|
||||
throw new FHIRException("Exception evaluating "+src+": limit is not followed by ':'");
|
||||
}
|
||||
cnt = cnt.substring(1).trim();
|
||||
int i = 0;
|
||||
while (i < cnt.length() && Character.isDigit(cnt.charAt(i))) {
|
||||
i++;
|
||||
}
|
||||
if (i == 0) {
|
||||
throw new FHIRException("Exception evaluating "+src+": limit is not followed by a number");
|
||||
}
|
||||
limit = Integer.parseInt(cnt.substring(0, i));
|
||||
cnt = cnt.substring(i);
|
||||
} else if (cnt.startsWith("offset")) {
|
||||
cnt = cnt.substring(6).trim();
|
||||
if (!cnt.startsWith(":")) {
|
||||
throw new FHIRException("Exception evaluating "+src+": limit is not followed by ':'");
|
||||
}
|
||||
cnt = cnt.substring(1).trim();
|
||||
int i = 0;
|
||||
while (i < cnt.length() && Character.isDigit(cnt.charAt(i))) {
|
||||
i++;
|
||||
}
|
||||
if (i == 0) {
|
||||
throw new FHIRException("Exception evaluating "+src+": limit is not followed by a number");
|
||||
}
|
||||
offset = Integer.parseInt(cnt.substring(0, i));
|
||||
cnt = cnt.substring(i);
|
||||
} else {
|
||||
throw new FHIRException("Exception evaluating "+src+": unexpected content at "+cnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,11 +329,11 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
private Map<String, ExpressionNode> params = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void evaluate(StringBuilder b, Resource resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||
String src = includeResolver.fetchInclude(LiquidEngine.this, page);
|
||||
LiquidParser parser = new LiquidParser(src);
|
||||
LiquidDocument doc = parser.parse(page);
|
||||
LiquidEngineContext nctxt = new LiquidEngineContext(ctxt.externalContext);
|
||||
LiquidEngineContext nctxt = new LiquidEngineContext(ctxt.externalContext);
|
||||
Tuple incl = new Tuple();
|
||||
nctxt.vars.put("include", incl);
|
||||
for (String s : params.keySet()) {
|
||||
|
@ -201,7 +345,7 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
}
|
||||
}
|
||||
|
||||
public static class LiquidDocument {
|
||||
public static class LiquidDocument {
|
||||
private List<LiquidNode> body = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
@ -225,64 +369,124 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
}
|
||||
|
||||
private char next2() {
|
||||
if (cursor >= source.length()-1)
|
||||
if (cursor >= source.length() - 1)
|
||||
return 0;
|
||||
else
|
||||
return source.charAt(cursor+1);
|
||||
return source.charAt(cursor + 1);
|
||||
}
|
||||
|
||||
private char grab() {
|
||||
cursor++;
|
||||
return source.charAt(cursor-1);
|
||||
return source.charAt(cursor - 1);
|
||||
}
|
||||
|
||||
public LiquidDocument parse(String name) throws FHIRException {
|
||||
this.name = name;
|
||||
LiquidDocument doc = new LiquidDocument();
|
||||
parseList(doc.body, new String[0]);
|
||||
parseList(doc.body, false, new String[0]);
|
||||
return doc;
|
||||
}
|
||||
|
||||
private String parseList(List<LiquidNode> list, String[] terminators) throws FHIRException {
|
||||
public LiquidCycle parseCycle(String cnt) {
|
||||
LiquidCycle res = new LiquidCycle();
|
||||
cnt = "," + cnt.substring(5).trim();
|
||||
while (!Utilities.noString(cnt)) {
|
||||
if (!cnt.startsWith(",")) {
|
||||
throw new FHIRException("Script " + name + ": Script " + name + ": Found " + cnt.charAt(0) + " expecting ',' parsing cycle");
|
||||
}
|
||||
cnt = cnt.substring(1).trim();
|
||||
if (!cnt.startsWith("\"")) {
|
||||
throw new FHIRException("Script " + name + ": Script " + name + ": Found " + cnt.charAt(0) + " expecting '\"' parsing cycle");
|
||||
}
|
||||
cnt = cnt.substring(1);
|
||||
int i = 0;
|
||||
while (i < cnt.length() && cnt.charAt(i) != '"') {
|
||||
i++;
|
||||
}
|
||||
if (i == cnt.length()) {
|
||||
throw new FHIRException("Script " + name + ": Script " + name + ": Found unterminated string parsing cycle");
|
||||
}
|
||||
res.list.add(cnt.substring(0, i));
|
||||
cnt = cnt.substring(i + 1).trim();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private String parseList(List<LiquidNode> list, boolean inLoop, String[] terminators) throws FHIRException {
|
||||
String close = null;
|
||||
while (cursor < source.length()) {
|
||||
if (next1() == '{' && (next2() == '%' || next2() == '{' )) {
|
||||
if (next2() == '%') {
|
||||
if (next1() == '{' && (next2() == '%' || next2() == '{')) {
|
||||
if (next2() == '%') {
|
||||
String cnt = parseTag('%');
|
||||
if (Utilities.existsInList(cnt, terminators)) {
|
||||
if (isTerminator(cnt, terminators)) {
|
||||
close = cnt;
|
||||
break;
|
||||
} else if (cnt.startsWith("if "))
|
||||
list.add(parseIf(cnt));
|
||||
else if (cnt.startsWith("loop "))
|
||||
list.add(parseIf(cnt, inLoop));
|
||||
else if (cnt.startsWith("loop ")) // loop is deprecated, but still
|
||||
// supported
|
||||
list.add(parseLoop(cnt.substring(4).trim()));
|
||||
else if (cnt.startsWith("for "))
|
||||
list.add(parseFor(cnt.substring(3).trim()));
|
||||
else if (inLoop && cnt.equals("continue"))
|
||||
list.add(new LiquidContinue());
|
||||
else if (inLoop && cnt.equals("break"))
|
||||
list.add(new LiquidBreak());
|
||||
else if (inLoop && cnt.startsWith("cycle "))
|
||||
list.add(parseCycle(cnt));
|
||||
else if (cnt.startsWith("include "))
|
||||
list.add(parseInclude(cnt.substring(7).trim()));
|
||||
else
|
||||
throw new FHIRException("Script "+name+": Script "+name+": Unknown flow control statement "+cnt);
|
||||
throw new FHIRException("Script " + name + ": Script " + name + ": Unknown flow control statement " + cnt);
|
||||
} else { // next2() == '{'
|
||||
list.add(parseStatement());
|
||||
}
|
||||
} else {
|
||||
if (list.size() == 0 || !(list.get(list.size()-1) instanceof LiquidConstant))
|
||||
if (list.size() == 0 || !(list.get(list.size() - 1) instanceof LiquidConstant))
|
||||
list.add(new LiquidConstant());
|
||||
((LiquidConstant) list.get(list.size()-1)).addChar(grab());
|
||||
((LiquidConstant) list.get(list.size() - 1)).addChar(grab());
|
||||
}
|
||||
}
|
||||
for (LiquidNode n : list)
|
||||
n.closeUp();
|
||||
if (terminators.length > 0)
|
||||
if (!Utilities.existsInList(close, terminators))
|
||||
throw new FHIRException("Script "+name+": Script "+name+": Found end of script looking for "+terminators);
|
||||
if (!isTerminator(close, terminators))
|
||||
throw new FHIRException("Script " + name + ": Script " + name + ": Found end of script looking for " + terminators);
|
||||
return close;
|
||||
}
|
||||
|
||||
private LiquidNode parseIf(String cnt) throws FHIRException {
|
||||
private boolean isTerminator(String cnt, String[] terminators) {
|
||||
if (Utilities.noString(cnt)) {
|
||||
return false;
|
||||
}
|
||||
for (String t : terminators) {
|
||||
if (t.endsWith(" ")) {
|
||||
if (cnt.startsWith(t)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (cnt.equals(t)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private LiquidNode parseIf(String cnt, boolean inLoop) throws FHIRException {
|
||||
LiquidIf res = new LiquidIf();
|
||||
res.condition = cnt.substring(3).trim();
|
||||
String term = parseList(res.thenBody, new String[] { "else", "endif"} );
|
||||
if ("else".equals(term))
|
||||
term = parseList(res.elseBody, new String[] { "endif"} );
|
||||
String term = parseList(res.thenBody, inLoop, new String[] { "else", "elsif ", "endif" });
|
||||
while (term.startsWith("elsif ")) {
|
||||
LiquidElsIf elsIf = new LiquidElsIf();
|
||||
res.elseIf.add(elsIf);
|
||||
elsIf.condition = term.substring(5).trim();
|
||||
term = parseList(elsIf.body, inLoop, new String[] { "elsif ", "else", "endif" });
|
||||
}
|
||||
if ("else".equals(term)) {
|
||||
term = parseList(res.elseBody, inLoop, new String[] { "endif" });
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -291,7 +495,7 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
while (i < cnt.length() && !Character.isWhitespace(cnt.charAt(i)))
|
||||
i++;
|
||||
if (i == cnt.length() || i == 0)
|
||||
throw new FHIRException("Script "+name+": Error reading include: "+cnt);
|
||||
throw new FHIRException("Script " + name + ": Error reading include: " + cnt);
|
||||
LiquidInclude res = new LiquidInclude();
|
||||
res.page = cnt.substring(0, i);
|
||||
while (i < cnt.length() && Character.isWhitespace(cnt.charAt(i)))
|
||||
|
@ -300,27 +504,26 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
int j = i;
|
||||
while (i < cnt.length() && cnt.charAt(i) != '=')
|
||||
i++;
|
||||
if (i >= cnt.length() || j == i)
|
||||
throw new FHIRException("Script "+name+": Error reading include: "+cnt);
|
||||
if (i >= cnt.length() || j == i)
|
||||
throw new FHIRException("Script " + name + ": Error reading include: " + cnt);
|
||||
String n = cnt.substring(j, i);
|
||||
if (res.params.containsKey(n))
|
||||
throw new FHIRException("Script "+name+": Error reading include: "+cnt);
|
||||
if (res.params.containsKey(n))
|
||||
throw new FHIRException("Script " + name + ": Error reading include: " + cnt);
|
||||
i++;
|
||||
ExpressionNodeWithOffset t = engine.parsePartial(cnt, i);
|
||||
i = t.getOffset();
|
||||
res.params.put(n, t.getNode());
|
||||
while (i < cnt.length() && Character.isWhitespace(cnt.charAt(i)))
|
||||
i++;
|
||||
ExpressionNodeWithOffset t = engine.parsePartial(cnt, i);
|
||||
i = t.getOffset();
|
||||
res.params.put(n, t.getNode());
|
||||
while (i < cnt.length() && Character.isWhitespace(cnt.charAt(i)))
|
||||
i++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
private LiquidNode parseLoop(String cnt) throws FHIRException {
|
||||
int i = 0;
|
||||
while (!Character.isWhitespace(cnt.charAt(i)))
|
||||
i++;
|
||||
LiquidLoop res = new LiquidLoop();
|
||||
LiquidFor res = new LiquidFor();
|
||||
res.varName = cnt.substring(0, i);
|
||||
while (Character.isWhitespace(cnt.charAt(i)))
|
||||
i++;
|
||||
|
@ -328,36 +531,58 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
while (!Character.isWhitespace(cnt.charAt(i)))
|
||||
i++;
|
||||
if (!"in".equals(cnt.substring(j, i)))
|
||||
throw new FHIRException("Script "+name+": Script "+name+": Error reading loop: "+cnt);
|
||||
throw new FHIRException("Script " + name + ": Script " + name + ": Error reading loop: " + cnt);
|
||||
res.condition = cnt.substring(i).trim();
|
||||
parseList(res.body, new String[] { "endloop"} );
|
||||
parseList(res.body, false, new String[] { "endloop" });
|
||||
return res;
|
||||
}
|
||||
|
||||
private LiquidNode parseFor(String cnt) throws FHIRException {
|
||||
int i = 0;
|
||||
while (!Character.isWhitespace(cnt.charAt(i)))
|
||||
i++;
|
||||
LiquidFor res = new LiquidFor();
|
||||
res.varName = cnt.substring(0, i);
|
||||
while (Character.isWhitespace(cnt.charAt(i)))
|
||||
i++;
|
||||
int j = i;
|
||||
while (!Character.isWhitespace(cnt.charAt(i)))
|
||||
i++;
|
||||
if (!"in".equals(cnt.substring(j, i)))
|
||||
throw new FHIRException("Script " + name + ": Script " + name + ": Error reading loop: " + cnt);
|
||||
res.condition = cnt.substring(i).trim();
|
||||
String term = parseList(res.body, true, new String[] { "endfor", "else" });
|
||||
if ("else".equals(term)) {
|
||||
parseList(res.elseBody, false, new String[] { "endfor" });
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
private String parseTag(char ch) throws FHIRException {
|
||||
grab();
|
||||
grab();
|
||||
grab();
|
||||
StringBuilder b = new StringBuilder();
|
||||
while (cursor < source.length() && !(next1() == '%' && next2() == '}')) {
|
||||
b.append(grab());
|
||||
}
|
||||
if (!(next1() == '%' && next2() == '}'))
|
||||
throw new FHIRException("Script "+name+": Unterminated Liquid statement {% "+b.toString());
|
||||
grab();
|
||||
if (!(next1() == '%' && next2() == '}'))
|
||||
throw new FHIRException("Script " + name + ": Unterminated Liquid statement {% " + b.toString());
|
||||
grab();
|
||||
grab();
|
||||
return b.toString().trim();
|
||||
}
|
||||
|
||||
private LiquidStatement parseStatement() throws FHIRException {
|
||||
grab();
|
||||
grab();
|
||||
grab();
|
||||
StringBuilder b = new StringBuilder();
|
||||
while (cursor < source.length() && !(next1() == '}' && next2() == '}')) {
|
||||
b.append(grab());
|
||||
}
|
||||
if (!(next1() == '}' && next2() == '}'))
|
||||
throw new FHIRException("Script "+name+": Unterminated Liquid statement {{ "+b.toString());
|
||||
grab();
|
||||
if (!(next1() == '}' && next2() == '}'))
|
||||
throw new FHIRException("Script " + name + ": Unterminated Liquid statement {{ " + b.toString());
|
||||
grab();
|
||||
grab();
|
||||
LiquidStatement res = new LiquidStatement();
|
||||
res.statement = b.toString().trim();
|
||||
|
@ -471,7 +696,7 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
if (!cnt.equals(node.getAttributes().get(an))) {
|
||||
node.getAttributes().put(an, cnt);
|
||||
replaced = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return replaced;
|
||||
|
|
|
@ -174,24 +174,27 @@ public class CDARoundTripTests {
|
|||
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void testSimple() throws IOException {
|
||||
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||
SimpleWorkerContext context = SimpleWorkerContext.fromPackage(pcm.loadPackage("hl7.fhir.r4.core", "4.0.1"));
|
||||
context.loadFromFile(TestingUtilities.loadTestResourceStream("r5", "cda", "any.xml"), "any.xml", null);
|
||||
context.loadFromFile(TestingUtilities.loadTestResourceStream("r5", "cda", "ii.xml"), "ii.xml", null);
|
||||
context.loadFromFile(TestingUtilities.loadTestResourceStream("r5", "cda", "cd.xml"), "cd.xml", null);
|
||||
context.loadFromFile(TestingUtilities.loadTestResourceStream("r5", "cda", "ce.xml"), "ce.xml", null);
|
||||
context.loadFromFile(TestingUtilities.loadTestResourceStream("r5", "cda", "cda.xml"), "cda.xml", null);
|
||||
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "any.xml"), "any.xml", null);
|
||||
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "ii.xml"), "ii.xml", null);
|
||||
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "cd.xml"), "cd.xml", null);
|
||||
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "ce.xml"), "ce.xml", null);
|
||||
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "ed.xml"), "ed.xml", null);
|
||||
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "st.xml"), "st.xml", null);
|
||||
context.loadFromFile(TestingUtilities.loadTestResourceStream("validator", "cda", "cda.xml"), "cda.xml", null);
|
||||
for (StructureDefinition sd : context.getStructures()) {
|
||||
if (!sd.hasSnapshot()) {
|
||||
System.out.println("generate snapshot for " + sd.getUrl());
|
||||
context.generateSnapshot(sd, true);
|
||||
}
|
||||
}
|
||||
Element cda = Manager.parse(context, TestingUtilities.loadTestResourceStream("r5", "cda", "example.xml"), FhirFormat.XML);
|
||||
Element cda = Manager.parse(context, TestingUtilities.loadTestResourceStream("validator", "cda", "example.xml"), FhirFormat.XML);
|
||||
FHIRPathEngine fp = new FHIRPathEngine(context);
|
||||
Assertions.assertEquals("2.16.840.1.113883.3.27.1776", fp.evaluateToString(null, cda, cda, cda, fp.parse("ClinicalDocument.templateId.root")));
|
||||
Assertions.assertEquals("SoEN", fp.evaluateToString(null, cda, cda, cda, fp.parse("ClinicalDocument.code.displayName")));
|
||||
Assertions.assertEquals("SoEN2", fp.evaluateToString(null, cda, cda, cda, fp.parse("ClinicalDocument.code.sdtcDisplayName")));
|
||||
}
|
||||
|
||||
}
|
|
@ -57,7 +57,7 @@ public class LiquidEngineTests implements ILiquidEngineIcludeResolver {
|
|||
this.test = test;
|
||||
LiquidDocument doc = engine.parse(test.get("template").getAsString(), "test-script");
|
||||
String output = engine.evaluate(doc, loadResource(), null);
|
||||
Assertions.assertTrue(test.get("output").getAsString().equals(output));
|
||||
Assertions.assertEquals(test.get("output").getAsString(), output);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -10,16 +10,20 @@ import java.util.stream.Stream;
|
|||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.formats.XmlParser;
|
||||
import org.hl7.fhir.r5.model.DomainResource;
|
||||
import org.hl7.fhir.r5.model.Questionnaire;
|
||||
import org.hl7.fhir.r5.renderers.RendererFactory;
|
||||
import org.hl7.fhir.r5.renderers.ResourceRenderer;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.QuestionnaireRendererMode;
|
||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode;
|
||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||
import org.hl7.fhir.utilities.TerminologyServiceOptions;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
|
||||
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||
|
@ -35,6 +39,8 @@ import org.xml.sax.SAXException;
|
|||
|
||||
public class NarrativeGenerationTests {
|
||||
|
||||
public static final String WINDOWS = "WINDOWS";
|
||||
|
||||
private static final String HEADER = "<html><head>"+
|
||||
"<link rel=\"stylesheet\" href=\"http://hl7.org/fhir/fhir.css\"/>"+
|
||||
"<link rel=\"stylesheet\" href=\"http://hl7.org/fhir/dist/css/bootstrap.css\"/>"+
|
||||
|
@ -87,10 +93,11 @@ public class NarrativeGenerationTests {
|
|||
@ParameterizedTest(name = "{index}: file {0}")
|
||||
@MethodSource("data")
|
||||
public void test(String id, TestDetails test) throws Exception {
|
||||
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", null, ResourceRendererMode.RESOURCE);
|
||||
rc.setDestDir("C:\\work\\org.hl7.fhir\\packages\\packages\\hl7.fhir.pubpack\\package\\other\\");
|
||||
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
|
||||
rc.setDestDir("");
|
||||
rc.setHeader(test.isHeader());
|
||||
rc.setDefinitionsTarget("test.html");
|
||||
rc.setTerminologyServiceOptions(TerminologyServiceOptions.defaults());
|
||||
IOUtils.copy(TestingUtilities.loadTestResourceStream("r5", "narrative", test.getId() + "-expected.xml"), new FileOutputStream(TestingUtilities.tempFile("narrative", test.getId() + "-expected.xml")));
|
||||
DomainResource source = (DomainResource) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "narrative", test.getId() + "-input.xml"));
|
||||
DomainResource target = (DomainResource) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "narrative", test.getId() + "-expected.xml"));
|
||||
|
|
|
@ -24,7 +24,7 @@ public class NarrativeGeneratorTests {
|
|||
|
||||
@BeforeAll
|
||||
public static void setUp() throws FHIRException {
|
||||
rc = new RenderingContext(TestingUtilities.context(), null, null, "", "http://hl7.org/fhir", ResourceRendererMode.RESOURCE);
|
||||
rc = new RenderingContext(TestingUtilities.context(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -27,7 +27,7 @@ public class ResourceRoundTripTests {
|
|||
@Test
|
||||
public void test() throws IOException, FHIRException, EOperationOutcome {
|
||||
DomainResource res = (DomainResource) new XmlParser().parse(TestingUtilities.loadTestResourceStream("r5", "unicode.xml"));
|
||||
RenderingContext rc = new RenderingContext(TestingUtilities.context(), null, null, "", "http://hl7.org/fhir", ResourceRendererMode.RESOURCE);
|
||||
RenderingContext rc = new RenderingContext(TestingUtilities.context(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
|
||||
RendererFactory.factory(res, rc).render(res);
|
||||
IOUtils.copy(TestingUtilities.loadTestResourceStream("r5", "unicode.xml"), new FileOutputStream(TestingUtilities.tempFile("gen", "unicode.xml")));
|
||||
new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(TestingUtilities.tempFile("gen", "unicode.out.xml")), res);
|
||||
|
|
|
@ -550,7 +550,7 @@ public class SnapShotGenerationTests {
|
|||
throw e;
|
||||
}
|
||||
if (output.getDifferential().hasElement()) {
|
||||
RenderingContext rc = new RenderingContext(TestingUtilities.context(), null, null, "", "http://hl7.org/fhir", ResourceRendererMode.RESOURCE);
|
||||
RenderingContext rc = new RenderingContext(TestingUtilities.context(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
|
||||
rc.setProfileUtilities(new ProfileUtilities(TestingUtilities.context(), null, new TestPKP()));
|
||||
RendererFactory.factory(output, rc).render(output);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,117 +0,0 @@
|
|||
package org.hl7.fhir.r5.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlParser;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class UtilitiesTests {
|
||||
|
||||
private static final String XHTML_SIMPLE = "<div>Some Text</div>";
|
||||
private static final String XHTML_LANGS = "<div xml:lang=\"en-US\" lang=\"en-US\">Some Text</div>";
|
||||
|
||||
public static final String OSX = "OS X";
|
||||
public static final String MAC = "MAC";
|
||||
public static final String WINDOWS = "WINDOWS";
|
||||
public static final String LINUX = "Linux";
|
||||
|
||||
public static final String TEST_TXT = "test.txt";
|
||||
|
||||
public static final String LINUX_TEMP_DIR = "/tmp/";
|
||||
public static final String LINUX_USER_DIR = System.getProperty("user.home") + "/";
|
||||
public static final String LINUX_JAVA_HOME = System.getenv("JAVA_HOME") + "/";
|
||||
|
||||
public static final String WIN_TEMP_DIR = "c:\\temp\\";
|
||||
public static final String WIN_USER_DIR = System.getProperty("user.home") + "\\";
|
||||
public static final String WIN_JAVA_HOME = System.getenv("JAVA_HOME") + "\\";
|
||||
|
||||
public static final String OSX_USER_DIR = System.getProperty("user.home") + "/";
|
||||
public static final String OSX_JAVA_HOME = System.getenv("JAVA_HOME") + "/";
|
||||
|
||||
@DisplayName("Test Utilities.path maps temp directory correctly")
|
||||
public void testTempDirPath() throws IOException {
|
||||
Assertions.assertEquals(Utilities.path("[tmp]", TEST_TXT), getTempDirectory() + TEST_TXT);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test Utilities.path maps user directory correctly")
|
||||
public void testUserDirPath() throws IOException {
|
||||
Assertions.assertEquals(Utilities.path("[user]", TEST_TXT), getUserDirectory() + TEST_TXT);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test Utilities.path maps JAVA_HOME correctly")
|
||||
public void testJavaHomeDirPath() throws IOException {
|
||||
Assertions.assertEquals(Utilities.path("[JAVA_HOME]", TEST_TXT), getJavaHomeDirectory() + TEST_TXT);
|
||||
}
|
||||
|
||||
private String getJavaHomeDirectory() {
|
||||
String os = SystemUtils.OS_NAME;
|
||||
if (os.contains(OSX) || os.contains(MAC)) {
|
||||
return OSX_JAVA_HOME;
|
||||
} else if (os.contains(LINUX)) {
|
||||
return LINUX_JAVA_HOME;
|
||||
} else if (os.toUpperCase().contains(WINDOWS)) {
|
||||
return WIN_JAVA_HOME;
|
||||
} else {
|
||||
throw new IllegalStateException("OS not recognized...cannot verify created directories.");
|
||||
}
|
||||
}
|
||||
|
||||
private String getUserDirectory() {
|
||||
String os = SystemUtils.OS_NAME;
|
||||
if (os.contains(OSX) || os.contains(MAC)) {
|
||||
return OSX_USER_DIR;
|
||||
} else if (os.contains(LINUX)) {
|
||||
return LINUX_USER_DIR;
|
||||
} else if (os.toUpperCase().contains(WINDOWS)) {
|
||||
return WIN_USER_DIR;
|
||||
} else {
|
||||
throw new IllegalStateException("OS not recognized...cannot verify created directories.");
|
||||
}
|
||||
}
|
||||
|
||||
private String getTempDirectory() throws IOException {
|
||||
String os = SystemUtils.OS_NAME;
|
||||
if (os.contains(OSX) || os.contains(MAC)) {
|
||||
return getOsxTempDir();
|
||||
} else if (os.contains(LINUX)) {
|
||||
return LINUX_TEMP_DIR;
|
||||
} else if (os.toUpperCase().contains(WINDOWS)) {
|
||||
return WIN_TEMP_DIR;
|
||||
} else {
|
||||
throw new IllegalStateException("OS not recognized...cannot verify created directories.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getting the temporary directory in OSX is a little different from Linux and Windows. We need to create a temporary
|
||||
* file and then extract the directory path from it.
|
||||
*
|
||||
* @return Full path to tmp directory on OSX machines.
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String getOsxTempDir() throws IOException {
|
||||
File file = File.createTempFile("throwaway", ".file");
|
||||
return file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf('/')) + '/';
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXhtmlLangAttributes() throws IOException {
|
||||
run(XHTML_SIMPLE);
|
||||
run(XHTML_LANGS);
|
||||
}
|
||||
|
||||
public void run(String src) throws IOException {
|
||||
XhtmlNode node = new XhtmlParser().parse(src, "div");
|
||||
String xhtml = new XhtmlComposer(false).compose(node);
|
||||
Assertions.assertTrue(src.equals(xhtml));
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.0.2-SNAPSHOT</version>
|
||||
<version>5.0.5-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.0.2-SNAPSHOT</version>
|
||||
<version>5.0.5-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -652,12 +652,12 @@ public class Utilities {
|
|||
}
|
||||
|
||||
|
||||
private static boolean isDigit(char c) {
|
||||
public static boolean isDigit(char c) {
|
||||
return (c >= '0') && (c <= '9');
|
||||
}
|
||||
|
||||
|
||||
private static boolean isAlphabetic(char c) {
|
||||
public static boolean isAlphabetic(char c) {
|
||||
return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'));
|
||||
}
|
||||
|
||||
|
|
|
@ -46,11 +46,15 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileLock;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
@ -80,15 +84,17 @@ import java.util.Map.Entry;
|
|||
* @author Grahame Grieve
|
||||
*/
|
||||
public class FilesystemPackageCacheManager extends BasePackageCacheManager implements IPackageCacheManager {
|
||||
|
||||
public static final String PRIMARY_SERVER = "http://packages.fhir.org";
|
||||
public static final String SECONDARY_SERVER = "http://packages2.fhir.org/packages";
|
||||
// private static final String SECONDARY_SERVER = "http://local.fhir.org:960/packages";
|
||||
public static final String PACKAGE_REGEX = "^[a-z][a-z0-9\\_\\-]*(\\.[a-z0-9\\_\\-]+)+$";
|
||||
public static final String PACKAGE_VERSION_REGEX = "^[a-z][a-z0-9\\_\\-]*(\\.[a-z0-9\\_\\-]+)+\\#[a-z0-9\\-\\_]+(\\.[a-z0-9\\-\\_]+)*$";
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(FilesystemPackageCacheManager.class);
|
||||
private static final String CACHE_VERSION = "3"; // second version - see wiki page
|
||||
public static final String PRIMARY_SERVER = "http://packages.fhir.org";
|
||||
public static final String SECONDARY_SERVER = "http://packages2.fhir.org/packages";
|
||||
private String cacheFolder;
|
||||
private boolean progress = true;
|
||||
private List<NpmPackage> temporaryPackages = new ArrayList<NpmPackage>();
|
||||
private List<NpmPackage> temporaryPackages = new ArrayList<>();
|
||||
private boolean buildLoaded = false;
|
||||
private Map<String, String> ciList = new HashMap<String, String>();
|
||||
private JsonArray buildInfo;
|
||||
|
@ -126,11 +132,6 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
return cacheFolder;
|
||||
}
|
||||
|
||||
// private List<String> allUrls;
|
||||
// private Map<String, VersionHistory> historyCache = new HashMap<>();
|
||||
|
||||
// ========================= Initialization ============================================================================
|
||||
|
||||
private List<String> sorted(String[] keys) {
|
||||
List<String> names = new ArrayList<String>();
|
||||
for (String s : keys)
|
||||
|
@ -144,8 +145,6 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
return pi;
|
||||
}
|
||||
|
||||
// ========================= Utilities ============================================================================
|
||||
|
||||
private JsonObject fetchJson(String source) throws IOException {
|
||||
URL url = new URL(source);
|
||||
URLConnection c = url.openConnection();
|
||||
|
@ -155,16 +154,19 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
private void clearCache() throws IOException {
|
||||
for (File f : new File(cacheFolder).listFiles()) {
|
||||
if (f.isDirectory()) {
|
||||
Utilities.clearDirectory(f.getAbsolutePath());
|
||||
try {
|
||||
FileUtils.deleteDirectory(f);
|
||||
} catch (Exception e1) {
|
||||
new CacheLock(f.getName()).doWithLock(() -> {
|
||||
Utilities.clearDirectory(f.getAbsolutePath());
|
||||
try {
|
||||
FileUtils.deleteDirectory(f);
|
||||
} catch (Exception e2) {
|
||||
// just give up
|
||||
} catch (Exception e1) {
|
||||
try {
|
||||
FileUtils.deleteDirectory(f);
|
||||
} catch (Exception e2) {
|
||||
// just give up
|
||||
}
|
||||
}
|
||||
}
|
||||
return null; // must return something
|
||||
});
|
||||
} else if (!f.getName().equals("packages.ini"))
|
||||
FileUtils.forceDelete(f);
|
||||
}
|
||||
|
@ -198,7 +200,6 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private void listSpecs(Map<String, String> specList, String server) throws IOException {
|
||||
CachingPackageClient pc = new CachingPackageClient(server);
|
||||
List<PackageClient.PackageInfo> matches = pc.search(null, null, null, false);
|
||||
|
@ -256,6 +257,8 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
clearCache();
|
||||
}
|
||||
|
||||
// ========================= Utilities ============================================================================
|
||||
|
||||
/**
|
||||
* Remove a particular package from the cache
|
||||
*
|
||||
|
@ -264,15 +267,18 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
* @throws IOException
|
||||
*/
|
||||
public void removePackage(String id, String ver) throws IOException {
|
||||
String f = Utilities.path(cacheFolder, id + "#" + ver);
|
||||
File ff = new File(f);
|
||||
if (ff.exists()) {
|
||||
Utilities.clearDirectory(f);
|
||||
IniFile ini = new IniFile(Utilities.path(cacheFolder, "packages.ini"));
|
||||
ini.removeProperty("packages", id + "#" + ver);
|
||||
ini.save();
|
||||
ff.delete();
|
||||
}
|
||||
new CacheLock(id + "#" + ver).doWithLock(() -> {
|
||||
String f = Utilities.path(cacheFolder, id + "#" + ver);
|
||||
File ff = new File(f);
|
||||
if (ff.exists()) {
|
||||
Utilities.clearDirectory(f);
|
||||
IniFile ini = new IniFile(Utilities.path(cacheFolder, "packages.ini"));
|
||||
ini.removeProperty("packages", id + "#" + ver);
|
||||
ini.save();
|
||||
ff.delete();
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -311,9 +317,6 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
// ========================= Package Mgmt API =======================================================================
|
||||
|
||||
/**
|
||||
* Add an already fetched package to the cache
|
||||
*/
|
||||
|
@ -339,71 +342,78 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
if (version == null)
|
||||
version = npm.version();
|
||||
|
||||
String packRoot = Utilities.path(cacheFolder, id + "#" + version);
|
||||
try {
|
||||
Utilities.createDirectory(packRoot);
|
||||
Utilities.clearDirectory(packRoot);
|
||||
String v = version;
|
||||
return new CacheLock(id + "#" + version).doWithLock(() -> {
|
||||
NpmPackage pck = null;
|
||||
String packRoot = Utilities.path(cacheFolder, id + "#" + v);
|
||||
try {
|
||||
// ok, now we have a lock on it... check if something created it while we were waiting
|
||||
if (!new File(packRoot).exists()) {
|
||||
Utilities.createDirectory(packRoot);
|
||||
Utilities.clearDirectory(packRoot);
|
||||
|
||||
int i = 0;
|
||||
int c = 0;
|
||||
int size = 0;
|
||||
for (Entry<String, NpmPackageFolder> e : npm.getFolders().entrySet()) {
|
||||
String dir = e.getKey().equals("package") ? Utilities.path(packRoot, "package") : Utilities.path(packRoot, "package", e.getKey());
|
||||
;
|
||||
if (!(new File(dir).exists()))
|
||||
Utilities.createDirectory(dir);
|
||||
for (Entry<String, byte[]> fe : e.getValue().getContent().entrySet()) {
|
||||
String fn = Utilities.path(dir, fe.getKey());
|
||||
byte[] cnt = fe.getValue();
|
||||
TextFile.bytesToFile(cnt, fn);
|
||||
size = size + cnt.length;
|
||||
i++;
|
||||
if (progress && i % 50 == 0) {
|
||||
c++;
|
||||
System.out.print(".");
|
||||
if (c == 120) {
|
||||
System.out.println("");
|
||||
System.out.print(" ");
|
||||
c = 2;
|
||||
int i = 0;
|
||||
int c = 0;
|
||||
int size = 0;
|
||||
for (Entry<String, NpmPackageFolder> e : npm.getFolders().entrySet()) {
|
||||
String dir = e.getKey().equals("package") ? Utilities.path(packRoot, "package") : Utilities.path(packRoot, "package", e.getKey());
|
||||
if (!(new File(dir).exists()))
|
||||
Utilities.createDirectory(dir);
|
||||
for (Entry<String, byte[]> fe : e.getValue().getContent().entrySet()) {
|
||||
String fn = Utilities.path(dir, fe.getKey());
|
||||
byte[] cnt = fe.getValue();
|
||||
TextFile.bytesToFile(cnt, fn);
|
||||
size = size + cnt.length;
|
||||
i++;
|
||||
if (progress && i % 50 == 0) {
|
||||
c++;
|
||||
System.out.print(".");
|
||||
if (c == 120) {
|
||||
System.out.println("");
|
||||
System.out.print(" ");
|
||||
c = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IniFile ini = new IniFile(Utilities.path(cacheFolder, "packages.ini"));
|
||||
ini.setTimeStampFormat("yyyyMMddhhmmss");
|
||||
ini.setTimestampProperty("packages", id + "#" + version, Timestamp.from(Instant.now()), null);
|
||||
ini.setIntegerProperty("package-sizes", id + "#" + version, size, null);
|
||||
ini.save();
|
||||
if (progress)
|
||||
System.out.println(" done.");
|
||||
|
||||
NpmPackage pck = loadPackageInfo(packRoot);
|
||||
if (!id.equals(JSONUtil.str(npm.getNpm(), "name")) || !version.equals(JSONUtil.str(npm.getNpm(), "version"))) {
|
||||
if (!id.equals(JSONUtil.str(npm.getNpm(), "name"))) {
|
||||
npm.getNpm().addProperty("original-name", JSONUtil.str(npm.getNpm(), "name"));
|
||||
npm.getNpm().remove("name");
|
||||
npm.getNpm().addProperty("name", id);
|
||||
IniFile ini = new IniFile(Utilities.path(cacheFolder, "packages.ini"));
|
||||
ini.setTimeStampFormat("yyyyMMddhhmmss");
|
||||
ini.setTimestampProperty("packages", id + "#" + v, Timestamp.from(Instant.now()), null);
|
||||
ini.setIntegerProperty("package-sizes", id + "#" + v, size, null);
|
||||
ini.save();
|
||||
if (progress)
|
||||
System.out.println(" done.");
|
||||
}
|
||||
if (!version.equals(JSONUtil.str(npm.getNpm(), "version"))) {
|
||||
npm.getNpm().addProperty("original-version", JSONUtil.str(npm.getNpm(), "version"));
|
||||
npm.getNpm().remove("version");
|
||||
npm.getNpm().addProperty("version", version);
|
||||
pck = loadPackageInfo(packRoot);
|
||||
if (!id.equals(JSONUtil.str(npm.getNpm(), "name")) || !v.equals(JSONUtil.str(npm.getNpm(), "version"))) {
|
||||
if (!id.equals(JSONUtil.str(npm.getNpm(), "name"))) {
|
||||
npm.getNpm().addProperty("original-name", JSONUtil.str(npm.getNpm(), "name"));
|
||||
npm.getNpm().remove("name");
|
||||
npm.getNpm().addProperty("name", id);
|
||||
}
|
||||
if (!v.equals(JSONUtil.str(npm.getNpm(), "version"))) {
|
||||
npm.getNpm().addProperty("original-version", JSONUtil.str(npm.getNpm(), "version"));
|
||||
npm.getNpm().remove("version");
|
||||
npm.getNpm().addProperty("version", v);
|
||||
}
|
||||
TextFile.stringToFile(new GsonBuilder().setPrettyPrinting().create().toJson(npm.getNpm()), Utilities.path(cacheFolder, id + "#" + v, "package", "package.json"), false);
|
||||
}
|
||||
TextFile.stringToFile(new GsonBuilder().setPrettyPrinting().create().toJson(npm.getNpm()), Utilities.path(cacheFolder, id + "#" + version, "package", "package.json"), false);
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
// don't leave a half extracted package behind
|
||||
System.out.println("Clean up package " + packRoot + " because installation failed: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
Utilities.clearDirectory(packRoot);
|
||||
new File(packRoot).delete();
|
||||
} catch (Exception ei) {
|
||||
// nothing
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
return pck;
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
// don't leave a half extracted package behind
|
||||
Utilities.clearDirectory(packRoot);
|
||||
new File(packRoot).delete();
|
||||
} catch (Exception ei) {
|
||||
// nothing
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -461,7 +471,6 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
return addPackageToCache(id, version == null ? source.version : version, source.stream, source.url);
|
||||
}
|
||||
|
||||
|
||||
private InputStream fetchFromUrlSpecific(String source, boolean optional) throws FHIRException {
|
||||
try {
|
||||
URL url = new URL(source);
|
||||
|
@ -488,7 +497,6 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private String getPackageUrlFromBuildList(String packageId) throws IOException {
|
||||
checkBuildLoaded();
|
||||
for (JsonElement n : buildInfo) {
|
||||
|
@ -500,9 +508,6 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
// ---------- Current Build SubSystem --------------------------------------------------------------------------------------
|
||||
|
||||
private void addCIBuildSpecs(Map<String, String> specList) throws IOException {
|
||||
checkBuildLoaded();
|
||||
for (JsonElement n : buildInfo) {
|
||||
|
@ -524,6 +529,9 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
// ========================= Package Mgmt API =======================================================================
|
||||
|
||||
private String getPackageIdFromBuildList(String canonical) throws IOException {
|
||||
checkBuildLoaded();
|
||||
if (buildInfo != null) {
|
||||
|
@ -667,6 +675,9 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
// ---------- Current Build SubSystem --------------------------------------------------------------------------------------
|
||||
|
||||
private String fetchVersionTheOldWay(String id) throws IOException {
|
||||
String url = getUrlForPackage(id);
|
||||
if (url == null) {
|
||||
|
@ -710,7 +721,6 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* if you don't provide and implementation of this interface, the PackageCacheManager will use the web directly.
|
||||
* <p>
|
||||
|
@ -723,6 +733,10 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
InputStream resolvePackage(String packageId, String version);
|
||||
}
|
||||
|
||||
public interface CacheLockFunction<T> {
|
||||
T get() throws IOException;
|
||||
}
|
||||
|
||||
public class BuildRecordSorter implements Comparator<BuildRecord> {
|
||||
|
||||
@Override
|
||||
|
@ -765,6 +779,8 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class VersionHistory {
|
||||
private String id;
|
||||
private String canonical;
|
||||
|
@ -803,11 +819,39 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple
|
|||
}
|
||||
}
|
||||
|
||||
private static String userDir() throws IOException {
|
||||
return Utilities.path(System.getProperty("user.home"), ".fhir", "packages");
|
||||
public class CacheLock {
|
||||
|
||||
private final File lockFile;
|
||||
|
||||
public CacheLock(String name) throws IOException {
|
||||
this.lockFile = new File(cacheFolder, name + ".lock");
|
||||
if (!lockFile.isFile()) {
|
||||
TextFile.stringToFile("", lockFile);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T doWithLock(CacheLockFunction<T> f) throws FileNotFoundException, IOException {
|
||||
try (FileChannel channel = new RandomAccessFile(lockFile, "rw").getChannel()) {
|
||||
final FileLock fileLock = channel.lock();
|
||||
T result = null;
|
||||
try {
|
||||
result = f.get();
|
||||
} finally {
|
||||
fileLock.release();
|
||||
}
|
||||
if (!lockFile.delete()) {
|
||||
lockFile.deleteOnExit();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//public List<String> getUrls() throws IOException {
|
||||
// if (allUrls == null)
|
||||
// {
|
||||
|
|
|
@ -570,6 +570,9 @@ public class NpmPackage {
|
|||
|
||||
public boolean hasFile(String folder, String file) throws IOException {
|
||||
NpmPackageFolder f = folders.get(folder);
|
||||
if (f == null) {
|
||||
f = folders.get(Utilities.path("package", folder));
|
||||
}
|
||||
return f != null && f.hasFile(file);
|
||||
}
|
||||
|
||||
|
|
118
org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/cache/PackageHacker.java
vendored
Normal file
118
org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/cache/PackageHacker.java
vendored
Normal file
|
@ -0,0 +1,118 @@
|
|||
package org.hl7.fhir.utilities.cache;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* intenral use only - set the file name to edit in main(), and fill out the edit routine
|
||||
*
|
||||
* @author grahame
|
||||
*
|
||||
*/
|
||||
public class PackageHacker {
|
||||
|
||||
public static void main(String[] args) throws FileNotFoundException, IOException {
|
||||
new PackageHacker().edit("C:\\Users\\graha\\Downloads\\package.tgz");
|
||||
}
|
||||
|
||||
private void edit(String name) throws FileNotFoundException, IOException {
|
||||
File f = new File(name);
|
||||
if (!f.exists())
|
||||
throw new Error("Unable to find "+f.getAbsolutePath());
|
||||
|
||||
NpmPackage pck = NpmPackage.fromPackage(new FileInputStream(f));
|
||||
System.out.println("Altering Package "+f.getAbsolutePath());
|
||||
System.out.println(nice(pck.getNpm()));
|
||||
|
||||
change(pck.getNpm(), pck.getFolders().get("package").getContent());
|
||||
|
||||
System.out.println("Revised Package");
|
||||
System.out.println("=======================");
|
||||
System.out.println(nice(pck.getNpm()));
|
||||
System.out.println("=======================");
|
||||
System.out.print("save? y/n: ");
|
||||
int r = System.in.read();
|
||||
if (r == 'y') {
|
||||
f.renameTo(new File(Utilities.changeFileExt(name, ".tgz.bak")));
|
||||
pck.save(new FileOutputStream(f));
|
||||
}
|
||||
}
|
||||
|
||||
private String nice(JsonObject json) {
|
||||
return new GsonBuilder().setPrettyPrinting().create().toJson(json);
|
||||
}
|
||||
|
||||
private void change(JsonObject npm, Map<String, byte[]> content) throws FileNotFoundException, IOException {
|
||||
// fixVersions(npm);
|
||||
// npm.addProperty("name", "hl7.terminology");
|
||||
npm.addProperty("url", "http://terminology.hl7.org/1.0.0");
|
||||
// npm.remove("canonical");
|
||||
// npm.addProperty("canonical", "http://hl7.org/fhir/us/davinci-drug-formulary");
|
||||
//// npm.remove("description");
|
||||
//// npm.addProperty("description", "Group Wrapper that includes all the R4 packages");
|
||||
// npm.remove("url");
|
||||
// npm.addProperty("url", "http://hl7.org/fhir/us/davinci-drug-formulary/Jun2019");
|
||||
// JsonObject dep = npm.getAsJsonObject("dependencies");
|
||||
// dep.remove("hl7.fhir.r3.core");
|
||||
// dep.remove("hl7.fhir.r3.examples");
|
||||
// dep.remove("hl7.fhir.r3.expansions");
|
||||
// dep.remove("hl7.fhir.r3.elements");
|
||||
// dep.addProperty("hl7.fhir.r3.core", "4.0.1");
|
||||
// dep.addProperty("hl7.fhir.r3.examples", "4.0.1");
|
||||
// dep.addProperty("hl7.fhir.r3.expansions", "4.0.1");
|
||||
// dep.addProperty("hl7.fhir.r3.elements", "4.0.1");
|
||||
}
|
||||
|
||||
private void fixVersions(JsonObject npm) {
|
||||
npm.remove("fhirVersions");
|
||||
JsonArray a = new JsonArray();
|
||||
npm.add("fhirVersions", a);
|
||||
a.add("4.0.1");
|
||||
npm.remove("fhir-version-list");
|
||||
a = new JsonArray();
|
||||
npm.add("fhir-version-list", a);
|
||||
a.add("4.0.1");
|
||||
}
|
||||
|
||||
private void setProperty(JsonObject npm, String name, String value) {
|
||||
npm.remove("homepage");
|
||||
npm.addProperty("homepage", "http://hl7.org/fhir");
|
||||
}
|
||||
|
||||
private void fixNames(Map<String, byte[]> content) {
|
||||
List<String> names = new ArrayList<>();
|
||||
names.addAll(content.keySet());
|
||||
for (String s : names) {
|
||||
if (s.endsWith("json") && !s.endsWith(".json")) {
|
||||
String n = s.substring(0, s.length()-4)+".json";
|
||||
content.put(n, content.get(s));
|
||||
content.remove(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addContentFrom(String folder, Map<String, byte[]> content) throws FileNotFoundException, IOException {
|
||||
for (File f : new File(folder).listFiles()) {
|
||||
if (f.getName().endsWith(".json") && !f.getName().endsWith(".canonical.json")) {
|
||||
String cnt = TextFile.fileToString(f);
|
||||
if (cnt.contains("\"resourceType\"")) {
|
||||
content.put("package/"+f.getName(), TextFile.fileToBytes(f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -491,30 +491,10 @@ public class I18nConstants {
|
|||
public static final String MEASURE_M_CRITERIA_CQL_NO_ELM = "MEASURE_M_CRITERIA_CQL_NO_ELM";
|
||||
public static final String MEASURE_M_CRITERIA_CQL_ELM_NOT_VALID = "MEASURE_M_CRITERIA_CQL_ELM_NOT_VALID";
|
||||
public static final String MEASURE_M_CRITERIA_CQL_NOT_FOUND = "MEASURE_M_CRITERIA_CQL_NOT_FOUND";
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
//public static final String
|
||||
public static final String VALIDATION_VAL_PROFILE_WRONGTYPE2 = "Validation_VAL_Profile_WrongType2";
|
||||
public static final String XHTML_URL_EMPTY = "XHTML_URL_EMPTY";
|
||||
public static final String XHTML_URL_INVALID_CHARS = "XHTML_URL_INVALID_CHARS";
|
||||
public static final String TERMINOLOGY_TX_SYSTEM_HTTPS = "TERMINOLOGY_TX_SYSTEM_HTTPS";
|
||||
public static final String CODESYSTEM_CS_NO_VS_NOTCOMPLETE = "CODESYSTEM_CS_NO_VS_NOTCOMPLETE";
|
||||
public static final String VALIDATION_VAL_ILLEGAL_TYPE_CONSTRAINT = "VALIDATION_VAL_ILLEGAL_TYPE_CONSTRAINT";
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package org.hl7.fhir.utilities.tests;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class BaseTestingUtilities {
|
||||
|
||||
static public boolean silent;
|
||||
|
||||
public static String loadTestResource(String... paths) throws IOException {
|
||||
if (new File("../../fhir-test-cases").exists() && isTryToLoadFromFileSystem()) {
|
||||
String n = Utilities.path(System.getProperty("user.dir"), "..", "..", "fhir-test-cases", Utilities.path(paths));
|
||||
// ok, we'll resolve this locally
|
||||
return TextFile.fileToString(new File(n));
|
||||
} else {
|
||||
// resolve from the package
|
||||
String contents;
|
||||
String classpath = ("/org/hl7/fhir/testcases/" + Utilities.pathURL(paths));
|
||||
try (InputStream inputStream = BaseTestingUtilities.class.getResourceAsStream(classpath)) {
|
||||
if (inputStream == null) {
|
||||
throw new IOException("Can't find file on classpath: " + classpath);
|
||||
}
|
||||
contents = IOUtils.toString(inputStream, java.nio.charset.StandardCharsets.UTF_8);
|
||||
}
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
|
||||
public static InputStream loadTestResourceStream(String... paths) throws IOException {
|
||||
if (new File("../../fhir-test-cases").exists() && isTryToLoadFromFileSystem()) {
|
||||
String n = Utilities.path(System.getProperty("user.dir"), "..", "..", "fhir-test-cases", Utilities.path(paths));
|
||||
return new FileInputStream(n);
|
||||
} else {
|
||||
String classpath = ("/org/hl7/fhir/testcases/" + Utilities.pathURL(paths));
|
||||
InputStream s = BaseTestingUtilities.class.getResourceAsStream(classpath);
|
||||
if (s == null) {
|
||||
throw new Error("unable to find resource " + classpath);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] loadTestResourceBytes(String... paths) throws IOException {
|
||||
if (new File("../../fhir-test-cases").exists() && isTryToLoadFromFileSystem()) {
|
||||
String n = Utilities.path(System.getProperty("user.dir"), "..", "..", "fhir-test-cases", Utilities.path(paths));
|
||||
return TextFile.fileToBytes(n);
|
||||
} else {
|
||||
String classpath = ("/org/hl7/fhir/testcases/" + Utilities.pathURL(paths));
|
||||
InputStream s = BaseTestingUtilities.class.getResourceAsStream(classpath);
|
||||
if (s == null) {
|
||||
throw new Error("unable to find resource " + classpath);
|
||||
}
|
||||
return TextFile.streamToBytes(s);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean findTestResource(String... paths) throws IOException {
|
||||
if (new File("../../fhir-test-cases").exists() && isTryToLoadFromFileSystem()) {
|
||||
String n = Utilities.path(System.getProperty("user.dir"), "..", "..", "fhir-test-cases", Utilities.path(paths));
|
||||
return new File(n).exists();
|
||||
} else {
|
||||
String classpath = ("/org/hl7/fhir/testcases/" + Utilities.pathURL(paths));
|
||||
try {
|
||||
InputStream inputStream = BaseTestingUtilities.class.getResourceAsStream(classpath);
|
||||
return inputStream != null;
|
||||
} catch (Throwable t) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: JA need to figure out how to detect that we're running in maven
|
||||
public static boolean isTryToLoadFromFileSystem() {
|
||||
return !"true".equals(System.getProperty("dont_load_from_filesystem"));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.hl7.fhir.r5.utils.formats;
|
||||
package org.hl7.fhir.utilities.turtle;
|
||||
|
||||
/*
|
||||
Copyright (c) 2011+, HL7, Inc.
|
|
@ -506,6 +506,10 @@ public class XhtmlNode implements IBaseXhtml {
|
|||
return addTag("td");
|
||||
}
|
||||
|
||||
public XhtmlNode td(String clss) {
|
||||
return addTag("td").attribute("class", clss);
|
||||
}
|
||||
|
||||
public XhtmlNode colspan(String n) {
|
||||
return setAttribute("colspan", n);
|
||||
}
|
||||
|
@ -545,13 +549,31 @@ public class XhtmlNode implements IBaseXhtml {
|
|||
public XhtmlNode i() {
|
||||
return addTag("i");
|
||||
}
|
||||
|
||||
public XhtmlNode tx(String cnt) {
|
||||
return addText(cnt);
|
||||
}
|
||||
|
||||
public XhtmlNode tx(int cnt) {
|
||||
return addText(Integer.toString(cnt));
|
||||
}
|
||||
|
||||
public XhtmlNode ah(String href) {
|
||||
return addTag("a").attribute("href", href);
|
||||
}
|
||||
|
||||
public XhtmlNode ah(String href, String title) {
|
||||
return addTag("a").attribute("href", href).attribute("title", title);
|
||||
}
|
||||
|
||||
public XhtmlNode img(String src) {
|
||||
return addTag("img").attribute("src", src);
|
||||
}
|
||||
|
||||
public XhtmlNode img(String src, String title) {
|
||||
return addTag("img").attribute("src", src).attribute("title", title);
|
||||
}
|
||||
|
||||
public void an(String href) {
|
||||
addTag("a").attribute("name", href).tx(" ");
|
||||
}
|
||||
|
@ -659,6 +681,13 @@ public class XhtmlNode implements IBaseXhtml {
|
|||
return this;
|
||||
}
|
||||
|
||||
public XhtmlNode addChildren(XhtmlNode x) {
|
||||
if (x != null) {
|
||||
getChildNodes().addAll(x.getChildNodes());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public XhtmlNode input(String name, String type, String placeholder, int size) {
|
||||
XhtmlNode p = new XhtmlNode(NodeType.Element, "input");
|
||||
|
@ -686,7 +715,23 @@ public class XhtmlNode implements IBaseXhtml {
|
|||
getChildNodes().add(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
public XhtmlNode remove(XhtmlNode x) {
|
||||
getChildNodes().remove(x);
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void clear() {
|
||||
getChildNodes().clear();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -495,3 +495,6 @@ TYPE_SPECIFIC_CHECKS_DT_ATT_TOO_LONG = Attachment size is {0} bytes which exceed
|
|||
TYPE_SPECIFIC_CHECKS_DT_ATT_NO_CONTENT = Attachments have data and/or url, or else must have either contentType and/oor language
|
||||
TYPE_SPECIFIC_CHECKS_DT_BASE64_TOO_LONG = Base64 size is {0} bytes which exceeds the stated limit of {1} bytes
|
||||
TYPE_SPECIFIC_CHECKS_DT_DECIMAL_CHARS = Found {0} decimal places which exceeds the stated limit of {1} digits
|
||||
Validation_VAL_Profile_WrongType = Specified profile type was "{0}", but found type "{1}"
|
||||
Validation_VAL_Profile_WrongType2 = Type mismatch processing profile {0} at path {1}: The element type is {4}, but the profile {3} is for a different type {2}
|
||||
VALIDATION_VAL_ILLEGAL_TYPE_CONSTRAINT = Illegal constraint in profile {0} at path {1} - cannot constrain to type {2} from base types {3}
|
|
@ -1,7 +1,7 @@
|
|||
package org.hl7.fhir.utilities.tests;
|
||||
|
||||
import org.hl7.fhir.utilities.cache.CachingPackageClient;
|
||||
import org.hl7.fhir.utilities.cache.BasePackageClient.PackageInfo;
|
||||
import org.hl7.fhir.utilities.cache.PackageClient.PackageInfo;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.0.2-SNAPSHOT</version>
|
||||
<version>5.0.5-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>org.hl7.fhir.core</artifactId>
|
||||
<version>5.0.2-SNAPSHOT</version>
|
||||
<version>5.0.5-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -1167,7 +1167,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
|||
private OperationOutcome exceptionToOutcome(Exception ex) throws IOException, FHIRException, EOperationOutcome {
|
||||
OperationOutcome op = new OperationOutcome();
|
||||
op.addIssue().setCode(org.hl7.fhir.r5.model.OperationOutcome.IssueType.EXCEPTION).setSeverity(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity.FATAL).getDetails().setText(ex.getMessage());
|
||||
RenderingContext rc = new RenderingContext(context, null, null, "", "http://hl7.org/fhir", ResourceRendererMode.RESOURCE);
|
||||
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
|
||||
RendererFactory.factory(op, rc).render(op);
|
||||
return op;
|
||||
}
|
||||
|
@ -1183,7 +1183,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
|||
}
|
||||
op.getIssue().add(OperationOutcomeUtilities.convertToIssue(vm, op));
|
||||
}
|
||||
RenderingContext rc = new RenderingContext(context, null, null, "", "http://hl7.org/fhir", ResourceRendererMode.RESOURCE);
|
||||
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
|
||||
RendererFactory.factory(op, rc).render(op);
|
||||
return op;
|
||||
}
|
||||
|
@ -1241,7 +1241,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
|||
public DomainResource generate(String source, String version) throws Exception {
|
||||
Content cnt = loadContent(source, "validate");
|
||||
Resource res = loadResourceByVersion(version, cnt.focus, source);
|
||||
RenderingContext rc = new RenderingContext(context, null, null, "", "http://hl7.org/fhir", ResourceRendererMode.RESOURCE);
|
||||
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
|
||||
RendererFactory.factory(res, rc).render((DomainResource) res);
|
||||
return (DomainResource) res;
|
||||
}
|
||||
|
@ -1546,7 +1546,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
|||
}
|
||||
|
||||
private void genScanOutputItem(ScanOutputItem item, String filename) throws IOException, FHIRException, EOperationOutcome {
|
||||
RenderingContext rc = new RenderingContext(context, null, null, "", "http://hl7.org/fhir", ResourceRendererMode.RESOURCE);
|
||||
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
|
||||
rc.setNoSlowLookup(true);
|
||||
RendererFactory.factory(item.outcome, rc).render(item.outcome);
|
||||
String s = new XhtmlComposer(XhtmlComposer.HTML).compose(item.outcome.getText().getDiv());
|
||||
|
|
|
@ -731,7 +731,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
timeTracker.tx(t, System.nanoTime());
|
||||
if (ss) {
|
||||
t = System.nanoTime();
|
||||
ValidationResult s = context.validateCode(new ValidationOptions(stack.getWorkingLang()), system, code, checkDisplay ? display : null);
|
||||
ValidationResult s = checkCodeOnServer(stack, code, system, display, checkDisplay);
|
||||
timeTracker.tx(t, System.nanoTime());
|
||||
if (s == null)
|
||||
return true;
|
||||
|
@ -894,7 +894,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (!atLeastOneSystemIsSupported && binding.getStrength() == BindingStrength.EXAMPLE) {
|
||||
// ignore this since we can't validate but it doesn't matter..
|
||||
} else {
|
||||
ValidationResult vr = context.validateCode(new ValidationOptions(stack.getWorkingLang()).checkValueSetOnly(), cc, valueset); // we're going to validate the codings directly, so only check the valueset
|
||||
ValidationResult vr = checkCodeOnServer(stack, valueset, cc, true); // we're going to validate the codings directly, so only check the valueset
|
||||
if (!vr.isOk()) {
|
||||
bindingsOk = false;
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) {
|
||||
|
@ -936,7 +936,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (bindingsOk) {
|
||||
for (Coding nextCoding : cc.getCoding()) {
|
||||
if (isNotBlank(nextCoding.getCode()) && isNotBlank(nextCoding.getSystem()) && context.supportsSystem(nextCoding.getSystem())) {
|
||||
ValidationResult vr = context.validateCode(new ValidationOptions(stack.getWorkingLang()).noCheckValueSetMembership(), nextCoding, valueset);
|
||||
ValidationResult vr = checkCodeOnServer(stack, valueset, nextCoding, false);
|
||||
if (vr.getSeverity() != null) {
|
||||
if (vr.getSeverity() == IssueSeverity.INFORMATION) {
|
||||
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, vr.getMessage());
|
||||
|
@ -1003,7 +1003,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (!atLeastOneSystemIsSupported && binding.getStrength() == BindingStrength.EXAMPLE) {
|
||||
// ignore this since we can't validate but it doesn't matter..
|
||||
} else {
|
||||
ValidationResult vr = context.validateCode(new ValidationOptions(stack.getWorkingLang()), cc, valueset); // we're going to validate the codings directly
|
||||
ValidationResult vr = checkCodeOnServer(stack, valueset, cc, false); // we're going to validate the codings directly
|
||||
if (!vr.isOk()) {
|
||||
bindingsOk = false;
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure()) {
|
||||
|
@ -1047,7 +1047,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
String nextCode = nextCoding.getCode();
|
||||
String nextSystem = nextCoding.getSystem();
|
||||
if (isNotBlank(nextCode) && isNotBlank(nextSystem) && context.supportsSystem(nextSystem)) {
|
||||
ValidationResult vr = context.validateCode(new ValidationOptions(stack.getWorkingLang()), nextSystem, nextCode, null);
|
||||
ValidationResult vr = checkCodeOnServer(stack, nextCode, nextSystem, null, false);
|
||||
if (!vr.isOk()) {
|
||||
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CODE_NOTVALID, nextCode, nextSystem);
|
||||
}
|
||||
|
@ -1096,7 +1096,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
long t = System.nanoTime();
|
||||
ValidationResult vr = null;
|
||||
if (binding.getStrength() != BindingStrength.EXAMPLE) {
|
||||
vr = context.validateCode(new ValidationOptions(stack.getWorkingLang()), c, valueset);
|
||||
vr = checkCodeOnServer(stack, valueset, c, true);
|
||||
}
|
||||
timeTracker.tx(t, System.nanoTime());
|
||||
if (vr != null && !vr.isOk()) {
|
||||
|
@ -1221,7 +1221,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND, describeReference(maxVSUrl))) {
|
||||
try {
|
||||
long t = System.nanoTime();
|
||||
ValidationResult vr = context.validateCode(new ValidationOptions(stack.getWorkingLang()), cc, valueset);
|
||||
ValidationResult vr = checkCodeOnServer(stack, valueset, cc, false);
|
||||
timeTracker.tx(t, System.nanoTime());
|
||||
if (!vr.isOk()) {
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||
|
@ -1240,7 +1240,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND, describeReference(maxVSUrl))) {
|
||||
try {
|
||||
long t = System.nanoTime();
|
||||
ValidationResult vr = context.validateCode(new ValidationOptions(stack.getWorkingLang()), c, valueset);
|
||||
ValidationResult vr = checkCodeOnServer(stack, valueset, c, true);
|
||||
timeTracker.tx(t, System.nanoTime());
|
||||
if (!vr.isOk()) {
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||
|
@ -1259,7 +1259,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (warning(errors, IssueType.CODEINVALID, element.line(), element.col(), path, valueset != null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND, describeReference(maxVSUrl))) {
|
||||
try {
|
||||
long t = System.nanoTime();
|
||||
ValidationResult vr = context.validateCode(new ValidationOptions(stack.getWorkingLang()), value, valueset);
|
||||
ValidationResult vr = checkCodeOnServer(stack, valueset, value, new ValidationOptions(stack.getWorkingLang()));
|
||||
timeTracker.tx(t, System.nanoTime());
|
||||
if (!vr.isOk()) {
|
||||
if (vr.getErrorClass() != null && vr.getErrorClass().isInfrastructure())
|
||||
|
@ -1315,7 +1315,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
long t = System.nanoTime();
|
||||
ValidationResult vr = null;
|
||||
if (binding.getStrength() != BindingStrength.EXAMPLE) {
|
||||
vr = context.validateCode(new ValidationOptions(stack.getWorkingLang()), c, valueset);
|
||||
vr = checkCodeOnServer(stack, valueset, c, true);
|
||||
}
|
||||
timeTracker.tx(t, System.nanoTime());
|
||||
if (vr != null && !vr.isOk()) {
|
||||
|
@ -2100,7 +2100,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
ValidationResult vr = null;
|
||||
if (binding.getStrength() != BindingStrength.EXAMPLE) {
|
||||
ValidationOptions options = new ValidationOptions(stack.getWorkingLang()).guessSystem();
|
||||
vr = context.validateCode(options, value, vs);
|
||||
vr = checkCodeOnServer(stack, vs, value, options);
|
||||
}
|
||||
timeTracker.tx(t, System.nanoTime());
|
||||
if (vr != null && !vr.isOk()) {
|
||||
|
@ -4541,4 +4541,29 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
|
||||
|
||||
public ValidationResult checkCodeOnServer(NodeStack stack, ValueSet vs, String value, ValidationOptions options) {
|
||||
return context.validateCode(options, value, vs);
|
||||
}
|
||||
|
||||
// no delay on this one?
|
||||
public ValidationResult checkCodeOnServer(NodeStack stack, String code, String system, String display, boolean checkDisplay) {
|
||||
return context.validateCode(new ValidationOptions(stack.getWorkingLang()), system, code, checkDisplay ? display : null);
|
||||
}
|
||||
|
||||
public ValidationResult checkCodeOnServer(NodeStack stack, ValueSet valueset, Coding c, boolean checkMembership) {
|
||||
if (checkMembership) {
|
||||
return context.validateCode(new ValidationOptions(stack.getWorkingLang()), c, valueset);
|
||||
} else {
|
||||
return context.validateCode(new ValidationOptions(stack.getWorkingLang()).noCheckValueSetMembership(), c, valueset);
|
||||
}
|
||||
}
|
||||
|
||||
public ValidationResult checkCodeOnServer(NodeStack stack, ValueSet valueset, CodeableConcept cc, boolean vsOnly) {
|
||||
if (vsOnly) {
|
||||
return context.validateCode(new ValidationOptions(stack.getWorkingLang()).checkValueSetOnly(), cc, valueset);
|
||||
} else {
|
||||
return context.validateCode(new ValidationOptions(stack.getWorkingLang()), cc, valueset);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -10,7 +10,7 @@ import org.hl7.fhir.utilities.VersionUtilities;
|
|||
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||
import org.hl7.fhir.utilities.cache.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.cache.CachingPackageClient;
|
||||
import org.hl7.fhir.utilities.cache.BasePackageClient.PackageInfo;
|
||||
import org.hl7.fhir.utilities.cache.PackageClient.PackageInfo;
|
||||
import org.hl7.fhir.utilities.cache.ToolsVersion;
|
||||
|
||||
public class PackageValidator {
|
||||
|
|
|
@ -90,61 +90,61 @@ public class ComparisonTests {
|
|||
@MethodSource("data")
|
||||
public void test(String name, JsonObject content) throws Exception {
|
||||
this.content = content;
|
||||
|
||||
|
||||
if (content.has("use-test") && !content.get("use-test").getAsBoolean())
|
||||
return;
|
||||
|
||||
|
||||
if (context == null) {
|
||||
System.out.println("---- Load R5 ----------------------------------------------------------------");
|
||||
context = TestingUtilities.context();
|
||||
context = TestingUtilities.context();
|
||||
}
|
||||
|
||||
|
||||
if (!new File(Utilities.path("[tmp]", "comparison")).exists()) {
|
||||
System.out.println("---- Set up Output ----------------------------------------------------------");
|
||||
Utilities.createDirectory(Utilities.path("[tmp]", "comparison"));
|
||||
FilesystemPackageCacheManager pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||
NpmPackage npm = pcm.loadPackage("hl7.fhir.pubpack", "0.0.4");
|
||||
NpmPackage npm = pcm.loadPackage("hl7.fhir.pubpack", "0.0.5");
|
||||
for (String f : npm.list("other")) {
|
||||
TextFile.streamToFile(npm.load("other", f), Utilities.path("[tmp]", "comparison", f));
|
||||
}
|
||||
}
|
||||
System.out.println("---- " + name + " ----------------------------------------------------------------");
|
||||
System.out.println("---- " + name + " ----------------------------------------------------------------");
|
||||
CanonicalResource left = load("left");
|
||||
CanonicalResource right = load("right");
|
||||
|
||||
|
||||
ComparisonSession session = new ComparisonSession(context);
|
||||
|
||||
|
||||
if (left instanceof CodeSystem && right instanceof CodeSystem) {
|
||||
CodeSystemComparer cs = new CodeSystemComparer(session );
|
||||
CodeSystemComparer cs = new CodeSystemComparer(session);
|
||||
CodeSystemComparison csc = cs.compare((CodeSystem) left, (CodeSystem) right);
|
||||
Assertions.assertTrue(csc.getUnion().getConcept().size() > csc.getIntersection().getConcept().size());
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "comparison", name+"-union.json")), csc.getUnion());
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "comparison", name+"-intersection.json")), csc.getIntersection());
|
||||
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "comparison", name + "-union.json")), csc.getUnion());
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "comparison", name + "-intersection.json")), csc.getIntersection());
|
||||
|
||||
String xmle = new XhtmlComposer(true).compose(cs.renderErrors(csc));
|
||||
String xml1 = new XhtmlComposer(true).compose(cs.renderMetadata(csc, "", ""));
|
||||
String xml2 = new XhtmlComposer(true).compose(cs.renderConcepts(csc, "", ""));
|
||||
TextFile.stringToFile(HEADER+hd("Messages")+xmle+BREAK+hd("Metadata")+xml1+BREAK+hd("Concepts")+xml2+FOOTER, Utilities.path("[tmp]", "comparison", name+".html"));
|
||||
TextFile.stringToFile(HEADER + hd("Messages") + xmle + BREAK + hd("Metadata") + xml1 + BREAK + hd("Concepts") + xml2 + FOOTER, Utilities.path("[tmp]", "comparison", name + ".html"));
|
||||
checkOutcomes(csc.getMessages(), content);
|
||||
} else if (left instanceof ValueSet && right instanceof ValueSet) {
|
||||
ValueSetComparer cs = new ValueSetComparer(session);
|
||||
ValueSetComparison csc = cs.compare((ValueSet) left, (ValueSet) right);
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "comparison", name+"-union.json")), csc.getUnion());
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "comparison", name+"-intersection.json")), csc.getIntersection());
|
||||
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "comparison", name + "-union.json")), csc.getUnion());
|
||||
new org.hl7.fhir.r5.formats.JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path("[tmp]", "comparison", name + "-intersection.json")), csc.getIntersection());
|
||||
|
||||
String xmle = new XhtmlComposer(true).compose(cs.renderErrors(csc));
|
||||
String xml1 = new XhtmlComposer(true).compose(cs.renderMetadata(csc, "", ""));
|
||||
String xml2 = new XhtmlComposer(true).compose(cs.renderCompose(csc, "", ""));
|
||||
String xml3 = new XhtmlComposer(true).compose(cs.renderExpansion(csc, "", ""));
|
||||
TextFile.stringToFile(HEADER+hd("Messages")+xmle+BREAK+hd("Metadata")+xml1+BREAK+hd("Definition")+xml2+BREAK+hd("Expansion")+xml3+FOOTER, Utilities.path("[tmp]", "comparison", name+".html"));
|
||||
TextFile.stringToFile(HEADER + hd("Messages") + xmle + BREAK + hd("Metadata") + xml1 + BREAK + hd("Definition") + xml2 + BREAK + hd("Expansion") + xml3 + FOOTER, Utilities.path("[tmp]", "comparison", name + ".html"));
|
||||
checkOutcomes(csc.getMessages(), content);
|
||||
} else {
|
||||
throw new FHIRException("Can't compare "+left.fhirType()+" to "+right.fhirType());
|
||||
throw new FHIRException("Can't compare " + left.fhirType() + " to " + right.fhirType());
|
||||
}
|
||||
}
|
||||
|
||||
private String hd(String text) {
|
||||
return "<h2>"+text+"</h2>\r\n";
|
||||
return "<h2>" + text + "</h2>\r\n";
|
||||
}
|
||||
|
||||
private CanonicalResource load(String name) throws IOException {
|
||||
|
@ -183,7 +183,7 @@ public class ComparisonTests {
|
|||
throw new FHIRException("unknown version " + ver);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkOutcomes(List<ValidationMessage> errors, JsonObject focus) {
|
||||
JsonObject output = focus.getAsJsonObject("output");
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
package org.hl7.fhir.conversion.tests;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses({
|
||||
SnapShotGenerationTestsX.class})
|
||||
public class CrossVersionLibraryTests {
|
||||
|
||||
}
|
|
@ -520,7 +520,8 @@ public class SnapShotGenerationTestsX {
|
|||
throw e;
|
||||
}
|
||||
if (output.getDifferential().hasElement()) {
|
||||
RenderingContext rc = new RenderingContext(TestingUtilities.context(), null, null, "", "http://hl7.org/fhir", ResourceRendererMode.RESOURCE);
|
||||
RenderingContext rc = new RenderingContext(TestingUtilities.context(), null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
|
||||
rc.setDestDir(makeTempDir());
|
||||
rc.setProfileUtilities(new ProfileUtilities(TestingUtilities.context(), null, new TestPKP()));
|
||||
RendererFactory.factory(output, rc).render(output);
|
||||
}
|
||||
|
@ -540,6 +541,13 @@ public class SnapShotGenerationTestsX {
|
|||
}
|
||||
}
|
||||
|
||||
private String makeTempDir() throws IOException {
|
||||
String path = Utilities.path("[tmp]", "snapshot");
|
||||
Utilities.createDirectory(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
private StructureDefinition getSD(String url) throws DefinitionException, FHIRException, IOException {
|
||||
StructureDefinition sd = context.getByUrl(url);
|
||||
if (sd == null)
|
||||
|
|
5
pom.xml
5
pom.xml
|
@ -13,11 +13,11 @@
|
|||
each other. It is fine to bump the point version of this POM without affecting
|
||||
HAPI FHIR.
|
||||
-->
|
||||
<version>5.0.2-SNAPSHOT</version>
|
||||
<version>5.0.5-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<hapi_fhir_version>5.0.0</hapi_fhir_version>
|
||||
<validator_test_case_version>1.1.14</validator_test_case_version>
|
||||
<validator_test_case_version>1.1.17</validator_test_case_version>
|
||||
<junit_jupiter_version>5.6.2</junit_jupiter_version>
|
||||
<maven_surefire_version>3.0.0-M4</maven_surefire_version>
|
||||
<jacoco_version>0.8.5</jacoco_version>
|
||||
|
@ -136,6 +136,7 @@
|
|||
<module>org.hl7.fhir.report</module>
|
||||
</modules>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
|
|
@ -8,6 +8,27 @@ title: FHIR Validator Release Notes
|
|||
|
||||
(no changes yet)
|
||||
|
||||
## v5.0.5 (2020-05-30)
|
||||
|
||||
|
||||
(no changes yet)
|
||||
|
||||
## v5.0.5 (2020-05-30)
|
||||
|
||||
|
||||
* Snapshot Generator: Add more testing for type consistency when profiling elements
|
||||
* Snapshot Generator: Fix bug constraining elements once they are sliced
|
||||
* Add support for http://hl7.org/fhir/StructureDefinition/elementdefinition-xml-name for CDA use
|
||||
|
||||
## v5.0.4 (2020-05-27)
|
||||
|
||||
(no changes yet)
|
||||
|
||||
## v5.0.3 (2020-05-26)
|
||||
|
||||
|
||||
* Fix for Core issue #95 - recursion on profile definition
|
||||
|
||||
## v5.0.2 (2020-05-22)
|
||||
|
||||
|
||||
|
@ -194,4 +215,4 @@ title: FHIR Validator Release Notes
|
|||
|
||||
## v4.1.60 (2020-02-02)
|
||||
|
||||
* This r
|
||||
* Th
|
|
@ -1,7 +1,7 @@
|
|||
@echo off
|
||||
|
||||
set oldver=4.2.31
|
||||
set newver=5.0.2
|
||||
set oldver=5.0.4
|
||||
set newver=5.0.5
|
||||
|
||||
echo ..
|
||||
echo =========================================================================
|
||||
|
|
Loading…
Reference in New Issue