Merge pull request #1440 from hapifhir/2023-09-gg-type-performance
2023 09 gg type performance
This commit is contained in:
commit
d2dfce22f9
|
@ -136,6 +136,7 @@ public class PackageVisitor {
|
|||
System.out.println("Go: "+pidList.size()+" published packages");
|
||||
i = 0;
|
||||
for (String pid : pidList) {
|
||||
if (pid != null) {
|
||||
if (!cpidSet.contains(pid)) {
|
||||
cpidSet.add(pid);
|
||||
List<String> vList = listVersions(pid);
|
||||
|
@ -151,6 +152,7 @@ public class PackageVisitor {
|
|||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
JsonObject json = JsonParser.parseObjectFromUrl("https://raw.githubusercontent.com/FHIR/ig-registry/master/fhir-ig-list.json");
|
||||
i = 0;
|
||||
List<JsonObject> objects = json.getJsonObjects("guides");
|
||||
|
@ -192,8 +194,8 @@ public class PackageVisitor {
|
|||
long ms2 = System.currentTimeMillis();
|
||||
|
||||
if (corePackages || !corePackage(npm)) {
|
||||
int c = 0;
|
||||
if (fv != null && (versions.isEmpty() || versions.contains(fv))) {
|
||||
int c = 0;
|
||||
for (String type : resourceTypes) {
|
||||
for (String s : npm.listResources(type)) {
|
||||
c++;
|
||||
|
@ -205,8 +207,10 @@ public class PackageVisitor {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Processed: "+pid+"#current: "+c+" resources ("+i+" of "+t+", "+(ms2-ms1)+"/"+(System.currentTimeMillis()-ms2)+"ms)");
|
||||
} else {
|
||||
System.out.println("Ignored: "+pid+"#current: no version");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Unable to process: "+pid+"#current: "+e.getMessage());
|
||||
|
@ -262,7 +266,7 @@ public class PackageVisitor {
|
|||
for (Element channel : XMLUtil.getNamedChildren(xml.getDocumentElement(), "channel")) {
|
||||
for (Element item : XMLUtil.getNamedChildren(channel, "item")) {
|
||||
String pid = XMLUtil.getNamedChildText(item, "title");
|
||||
if (pid.contains("#")) {
|
||||
if (pid != null && pid.contains("#")) {
|
||||
list.add(pid.substring(0, pid.indexOf("#")));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,9 +88,11 @@ public class TerminologyClientR4 implements ITerminologyClient {
|
|||
vs2 = client.expandValueset(vs2, p2, params); // todo: second parameter
|
||||
return (ValueSet) VersionConvertorFactory_40_50.convertResource(vs2);
|
||||
} catch (org.hl7.fhir.r4.utils.client.EFhirClientException e) {
|
||||
throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getMessage(),
|
||||
(org.hl7.fhir.r5.model.OperationOutcome) VersionConvertorFactory_40_50.convertResource(e.getServerErrors().get(0)));
|
||||
|
||||
if (e.getServerErrors().size() > 0) {
|
||||
throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getMessage(), (org.hl7.fhir.r5.model.OperationOutcome) VersionConvertorFactory_40_50.convertResource(e.getServerErrors().get(0)));
|
||||
} else {
|
||||
throw new org.hl7.fhir.r5.utils.client.EFhirClientException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,7 +167,8 @@ public class TerminologyClientR4 implements ITerminologyClient {
|
|||
|
||||
@Override
|
||||
public Bundle validateBatch(Bundle batch) {
|
||||
return (Bundle) VersionConvertorFactory_40_50.convertResource(client.transaction((org.hl7.fhir.r4.model.Bundle) VersionConvertorFactory_40_50.convertResource(batch)));
|
||||
org.hl7.fhir.r4.model.Bundle result = client.transaction((org.hl7.fhir.r4.model.Bundle) VersionConvertorFactory_40_50.convertResource(batch));
|
||||
return result == null ? null : (Bundle) VersionConvertorFactory_40_50.convertResource(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -449,8 +449,14 @@ public class FHIRToolingClient {
|
|||
throw new EFhirClientException("Server returned error code " + result.getHttpStatus(),
|
||||
(OperationOutcome) result.getPayload());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new FHIRException(e);
|
||||
} catch (EFhirClientException e) {
|
||||
if (e.getServerErrors().size() > 0) {
|
||||
throw new EFhirClientException(e.getMessage(), e.getServerErrors().get(0));
|
||||
} else {
|
||||
throw new EFhirClientException(e.getMessage(), e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new EFhirClientException(e.getMessage(), e);
|
||||
}
|
||||
return result == null ? null : (ValueSet) result.getPayload();
|
||||
}
|
||||
|
|
|
@ -273,7 +273,12 @@ public class FhirRequestBuilder {
|
|||
}
|
||||
|
||||
if (error != null) {
|
||||
throw new EFhirClientException("Error from server: " + ResourceUtilities.getErrorDescription(error), error);
|
||||
String s = ResourceUtilities.getErrorDescription(error);
|
||||
System.out.println(s);
|
||||
if (s.startsWith("Unable to find value set")) {
|
||||
System.out.println("!");
|
||||
}
|
||||
throw new EFhirClientException("Error from "+source+": " + ResourceUtilities.getErrorDescription(error), error);
|
||||
}
|
||||
|
||||
return resource;
|
||||
|
|
|
@ -180,6 +180,9 @@ public class ComparisonSession {
|
|||
}
|
||||
|
||||
private VersionComparisonAnnotation getAnnotation(Base b) {
|
||||
if (b == null) {
|
||||
return null;
|
||||
}
|
||||
if (b.hasUserData(VersionComparisonAnnotation.USER_DATA_NAME)) {
|
||||
return (VersionComparisonAnnotation) b.getUserData(VersionComparisonAnnotation.USER_DATA_NAME);
|
||||
} else {
|
||||
|
@ -203,8 +206,14 @@ public class ComparisonSession {
|
|||
|
||||
public void markDeleted(Base parent, String name, Base other) {
|
||||
if (isAnnotate() && other != null) {
|
||||
getAnnotation(parent).deleted(name, other);
|
||||
getAnnotation(other).deleted();
|
||||
VersionComparisonAnnotation annotation = getAnnotation(parent);
|
||||
if (annotation != null) {
|
||||
annotation.deleted(name, other);
|
||||
}
|
||||
annotation = getAnnotation(other);
|
||||
if (annotation != null) {
|
||||
annotation.deleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3431,7 +3431,8 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
|
||||
private void compareDiffs(List<ElementDefinition> diffList, List<ElementDefinition> newDiff, List<String> errors) {
|
||||
if (diffList.size() != newDiff.size()) {
|
||||
errors.add("The diff list size changed when sorting - was "+diffList.size()+" is now "+newDiff.size());
|
||||
errors.add("The diff list size changed when sorting - was "+diffList.size()+" is now "+newDiff.size()+
|
||||
" ["+CommaSeparatedStringBuilder.buildObjects(diffList)+"]/["+CommaSeparatedStringBuilder.buildObjects(newDiff)+"]");
|
||||
} else {
|
||||
for (int i = 0; i < Integer.min(diffList.size(), newDiff.size()); i++) {
|
||||
ElementDefinition e = diffList.get(i);
|
||||
|
|
|
@ -124,6 +124,7 @@ import org.hl7.fhir.r5.terminologies.client.TerminologyClientContext;
|
|||
import org.hl7.fhir.r5.utils.PackageHackerR5;
|
||||
import org.hl7.fhir.r5.utils.ResourceUtilities;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.r5.utils.client.EFhirClientException;
|
||||
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier;
|
||||
import org.hl7.fhir.utilities.TimeTracker;
|
||||
import org.hl7.fhir.utilities.ToolingClientLogger;
|
||||
|
@ -223,6 +224,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
private CanonicalResourceManager<ConceptMap> maps = new CanonicalResourceManager<ConceptMap>(false, minimalMemory);
|
||||
protected CanonicalResourceManager<StructureMap> transforms = new CanonicalResourceManager<StructureMap>(false, minimalMemory);
|
||||
private CanonicalResourceManager<StructureDefinition> structures = new CanonicalResourceManager<StructureDefinition>(false, minimalMemory);
|
||||
private TypeManager typeManager = new TypeManager(structures);
|
||||
private final CanonicalResourceManager<Measure> measures = new CanonicalResourceManager<Measure>(false, minimalMemory);
|
||||
private final CanonicalResourceManager<Library> libraries = new CanonicalResourceManager<Library>(false, minimalMemory);
|
||||
private CanonicalResourceManager<ImplementationGuide> guides = new CanonicalResourceManager<ImplementationGuide>(false, minimalMemory);
|
||||
|
@ -279,6 +281,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
this.valueSets = valueSets;
|
||||
this.maps = maps;
|
||||
this.structures = profiles;
|
||||
this.typeManager = new TypeManager(structures);
|
||||
this.guides = guides;
|
||||
clock = new TimeTracker();
|
||||
}
|
||||
|
@ -292,6 +295,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
maps.copy(other.maps);
|
||||
transforms.copy(other.transforms);
|
||||
structures.copy(other.structures);
|
||||
typeManager = new TypeManager(structures);
|
||||
searchParameters.copy(other.searchParameters);
|
||||
plans.copy(other.plans);
|
||||
questionnaires.copy(other.questionnaires);
|
||||
|
@ -370,6 +374,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
fixOldSD(sd);
|
||||
}
|
||||
structures.register(r, packageInfo);
|
||||
typeManager.see(r);
|
||||
break;
|
||||
case "ValueSet":
|
||||
valueSets.register(r, packageInfo);
|
||||
|
@ -462,6 +467,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
fixOldSD(sd);
|
||||
}
|
||||
structures.see(sd, packageInfo);
|
||||
typeManager.see(sd);
|
||||
} else if (r instanceof ValueSet) {
|
||||
valueSets.see((ValueSet) m, packageInfo);
|
||||
} else if (r instanceof CodeSystem) {
|
||||
|
@ -775,17 +781,21 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
|
||||
if (noTerminologyServer) {
|
||||
return new ValueSetExpansionOutcome(formatMessage(I18nConstants.ERROR_EXPANDING_VALUESET_RUNNING_WITHOUT_TERMINOLOGY_SERVICES), TerminologyServiceErrorClass.NOSERVICE);
|
||||
return new ValueSetExpansionOutcome(formatMessage(I18nConstants.ERROR_EXPANDING_VALUESET_RUNNING_WITHOUT_TERMINOLOGY_SERVICES), TerminologyServiceErrorClass.NOSERVICE, false);
|
||||
}
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("_limit", Integer.toString(expandCodesLimit ));
|
||||
params.put("_incomplete", "true");
|
||||
txLog("$expand on "+txCache.summary(vs));
|
||||
if (addDependentResources(p, vs)) {
|
||||
p.addParameter().setName("cache-id").setValue(new IdType(tcc.getCacheId()));
|
||||
}
|
||||
|
||||
try {
|
||||
ValueSet result = tcc.getClient().expandValueset(vs, p, params);
|
||||
res = new ValueSetExpansionOutcome(result).setTxLink(txLog.getLastId());
|
||||
} catch (Exception e) {
|
||||
res = new ValueSetExpansionOutcome(e.getMessage() == null ? e.getClass().getName() : e.getMessage(), TerminologyServiceErrorClass.UNKNOWN);
|
||||
res = new ValueSetExpansionOutcome(e.getMessage() == null ? e.getClass().getName() : e.getMessage(), TerminologyServiceErrorClass.UNKNOWN, true);
|
||||
if (txLog != null) {
|
||||
res.setTxLink(txLog.getLastId());
|
||||
}
|
||||
|
@ -815,7 +825,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
throw new Error(formatMessage(I18nConstants.NO_PARAMETERS_PROVIDED_TO_EXPANDVS));
|
||||
}
|
||||
if (vs.getUrl().equals("http://hl7.org/fhir/ValueSet/all-time-units") || vs.getUrl().equals("http://hl7.org/fhir/ValueSet/all-distance-units")) {
|
||||
return new ValueSetExpansionOutcome("This value set is not expanded correctly at this time (will be fixed in a future version)", TerminologyServiceErrorClass.VALUESET_UNSUPPORTED);
|
||||
return new ValueSetExpansionOutcome("This value set is not expanded correctly at this time (will be fixed in a future version)", TerminologyServiceErrorClass.VALUESET_UNSUPPORTED, false);
|
||||
}
|
||||
|
||||
Parameters p = pIn.copy();
|
||||
|
@ -857,7 +867,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
} catch (Exception e) {
|
||||
allErrors.addAll(vse.getAllErrors());
|
||||
e.printStackTrace();
|
||||
res = new ValueSetExpansionOutcome(e.getMessage(), TerminologyServiceErrorClass.UNKNOWN);
|
||||
res = new ValueSetExpansionOutcome(e.getMessage(), TerminologyServiceErrorClass.UNKNOWN, e instanceof EFhirClientException);
|
||||
}
|
||||
allErrors.addAll(vse.getAllErrors());
|
||||
if (res.getValueset() != null) {
|
||||
|
@ -868,17 +878,17 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
return res;
|
||||
}
|
||||
if (res.getErrorClass() == TerminologyServiceErrorClass.INTERNAL_ERROR || isNoTerminologyServer()) { // this class is created specifically to say: don't consult the server
|
||||
return new ValueSetExpansionOutcome(res.getError(), res.getErrorClass());
|
||||
return new ValueSetExpansionOutcome(res.getError(), res.getErrorClass(), false);
|
||||
}
|
||||
|
||||
// if that failed, we try to expand on the server
|
||||
if (addDependentResources(p, vs)) {
|
||||
p.addParameter().setName("cache-id").setValue(new IdType(tcc.getCacheId()));
|
||||
if (noTerminologyServer) {
|
||||
return new ValueSetExpansionOutcome(formatMessage(I18nConstants.ERROR_EXPANDING_VALUESET_RUNNING_WITHOUT_TERMINOLOGY_SERVICES), TerminologyServiceErrorClass.NOSERVICE, allErrors, false);
|
||||
}
|
||||
|
||||
if (noTerminologyServer) {
|
||||
return new ValueSetExpansionOutcome(formatMessage(I18nConstants.ERROR_EXPANDING_VALUESET_RUNNING_WITHOUT_TERMINOLOGY_SERVICES), TerminologyServiceErrorClass.NOSERVICE, allErrors);
|
||||
}
|
||||
p.addParameter().setName("cache-id").setValue(new IdType(tcc.getCacheId()));
|
||||
addDependentResources(p, vs);
|
||||
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("_limit", Integer.toString(expandCodesLimit ));
|
||||
params.put("_incomplete", "true");
|
||||
|
@ -893,7 +903,11 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
}
|
||||
res = new ValueSetExpansionOutcome(result).setTxLink(txLog.getLastId());
|
||||
} catch (Exception e) {
|
||||
res = new ValueSetExpansionOutcome((e.getMessage() == null ? e.getClass().getName() : e.getMessage()), TerminologyServiceErrorClass.UNKNOWN, allErrors).setTxLink(txLog == null ? null : txLog.getLastId());
|
||||
if (res != null && !res.isFromServer()) {
|
||||
res = new ValueSetExpansionOutcome(res.getError()+" (and "+e.getMessage()+")", res.getErrorClass(), false);
|
||||
} else {
|
||||
res = new ValueSetExpansionOutcome((e.getMessage() == null ? e.getClass().getName() : e.getMessage()), TerminologyServiceErrorClass.UNKNOWN, allErrors, true).setTxLink(txLog == null ? null : txLog.getLastId());
|
||||
}
|
||||
}
|
||||
txCache.cacheExpansion(cacheToken, res, TerminologyCache.PERMANENT);
|
||||
return res;
|
||||
|
@ -1278,10 +1292,8 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
p.setParameter("includeDefinition", false);
|
||||
p.setParameter("excludeNested", !hierarchical);
|
||||
|
||||
boolean cached = addDependentResources(p, vs);
|
||||
if (cached) {
|
||||
addDependentResources(p, vs);
|
||||
p.addParameter().setName("cache-id").setValue(new IdType(tcc.getCacheId()));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -1475,9 +1487,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
cache = true;
|
||||
addDependentResources(pin, vs);
|
||||
}
|
||||
if (cache) {
|
||||
pin.addParameter().setName("cache-id").setValue(new IdType(tcc.getCacheId()));
|
||||
}
|
||||
for (ParametersParameterComponent pp : pin.getParameter()) {
|
||||
if (pp.getName().equals("profile")) {
|
||||
throw new Error(formatMessage(I18nConstants.CAN_ONLY_SPECIFY_PROFILE_IN_THE_CONTEXT));
|
||||
|
@ -2337,6 +2347,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
|
||||
if (fhirType.equals("StructureDefinition")) {
|
||||
structures.drop(id);
|
||||
typeManager.reload();
|
||||
} else if (fhirType.equals("ImplementationGuide")) {
|
||||
guides.drop(id);
|
||||
} else if (fhirType.equals("CapabilityStatement")) {
|
||||
|
@ -2463,32 +2474,21 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
if (Utilities.isAbsoluteUrl(typeName)) {
|
||||
return fetchResource(StructureDefinition.class, typeName);
|
||||
} else {
|
||||
Set<StructureDefinition> types = new HashSet<>();
|
||||
types.addAll(fetchTypeDefinitions(typeName));
|
||||
types.removeIf(sd -> sd.getDerivation() == TypeDerivationRule.CONSTRAINT);
|
||||
if (types.size() == 0) {
|
||||
return null; // throw new FHIRException("Unresolved type "+typeName+" (0)");
|
||||
} else if (types.size() == 1) {
|
||||
return types.iterator().next();
|
||||
} else {
|
||||
types.removeIf(sd -> !sd.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition/"));
|
||||
if (types.size() == 0) {
|
||||
return null;
|
||||
} else if (types.size() != 1) {
|
||||
throw new FHIRException("Ambiguous type "+typeName+" ("+types.toString()+") (contact Grahame Grieve for investigation)");
|
||||
} else {
|
||||
return types.iterator().next();
|
||||
}
|
||||
}
|
||||
return typeManager.fetchTypeDefinition(typeName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StructureDefinition> fetchTypeDefinitions(String typeName) {
|
||||
List<StructureDefinition> res = new ArrayList<>();
|
||||
structures.listAll(res);
|
||||
res.removeIf(sd -> !sd.hasType() || !(sd.getType().equals(typeName) || sd.getTypeTail().equals(typeName)));
|
||||
return res;
|
||||
return typeManager.getDefinitions(typeName);
|
||||
}
|
||||
|
||||
public boolean isPrimitiveType(String type) {
|
||||
return typeManager.isPrimitive(type);
|
||||
}
|
||||
|
||||
public boolean isDataType(String type) {
|
||||
return typeManager.isDataType(type);
|
||||
}
|
||||
|
||||
public boolean isTlogging() {
|
||||
|
@ -2627,6 +2627,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte
|
|||
maps.setVersion(version);
|
||||
transforms.setVersion(version);
|
||||
structures.setVersion(version);
|
||||
typeManager.reload();
|
||||
measures.setVersion(version);
|
||||
libraries.setVersion(version);
|
||||
guides.setVersion(version);
|
||||
|
|
|
@ -31,10 +31,11 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
|||
private String url;
|
||||
private String version;
|
||||
private String supplements;
|
||||
private String derivation;
|
||||
private CanonicalResource resource;
|
||||
private boolean hacked;
|
||||
|
||||
public CanonicalResourceProxy(String type, String id, String url, String version, String supplements) {
|
||||
public CanonicalResourceProxy(String type, String id, String url, String version, String supplements, String derivation) {
|
||||
super();
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
|
@ -75,6 +76,14 @@ public class CanonicalResourceManager<T extends CanonicalResource> {
|
|||
return supplements;
|
||||
}
|
||||
|
||||
public String getDerivation() {
|
||||
return derivation;
|
||||
}
|
||||
|
||||
public void setDerivation(String derivation) {
|
||||
this.derivation = derivation;
|
||||
}
|
||||
|
||||
public CanonicalResource getResource() throws FHIRException {
|
||||
if (resource == null) {
|
||||
resource = loadResource();
|
||||
|
|
|
@ -310,8 +310,7 @@ public class ContextUtilities implements ProfileKnowledgeProvider {
|
|||
|
||||
@Override
|
||||
public boolean isPrimitiveType(String type) {
|
||||
StructureDefinition sd = context.fetchTypeDefinition(type);
|
||||
return sd != null && sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE;
|
||||
return context.isPrimitiveType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -364,11 +363,6 @@ public class ContextUtilities implements ProfileKnowledgeProvider {
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean isPrimitiveDatatype(String type) {
|
||||
StructureDefinition sd = context.fetchTypeDefinition(type);
|
||||
return sd != null && sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE;
|
||||
}
|
||||
|
||||
public StructureDefinition fetchByJsonName(String key) {
|
||||
for (StructureDefinition sd : context.fetchResourcesByType(StructureDefinition.class)) {
|
||||
ElementDefinition ed = sd.getSnapshot().getElementFirstRep();
|
||||
|
|
|
@ -938,6 +938,19 @@ public interface IWorkerContext {
|
|||
*/
|
||||
public List<StructureDefinition> fetchTypeDefinitions(String n);
|
||||
|
||||
/**
|
||||
* return whether type is primitive type. This is called a lot, and needs a high performance implementation
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
public boolean isPrimitiveType(String type);
|
||||
|
||||
/**
|
||||
* return whether type is data type. This is called a lot, and needs a high performance implementation
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
public boolean isDataType(String type);
|
||||
|
||||
/**
|
||||
* Returns a set of keys that can be used to get binaries from this context.
|
||||
|
@ -1020,4 +1033,6 @@ public interface IWorkerContext {
|
|||
|
||||
public boolean isForPublication();
|
||||
public void setForPublication(boolean value);
|
||||
|
||||
|
||||
}
|
|
@ -99,7 +99,7 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
|||
private final IContextResourceLoader loader;
|
||||
|
||||
public PackageResourceLoader(PackageResourceInformation pri, IContextResourceLoader loader) {
|
||||
super(pri.getResourceType(), pri.getId(), loader == null ? pri.getUrl() :loader.patchUrl(pri.getUrl(), pri.getResourceType()), pri.getVersion(), pri.getSupplements());
|
||||
super(pri.getResourceType(), pri.getId(), loader == null ? pri.getUrl() :loader.patchUrl(pri.getUrl(), pri.getResourceType()), pri.getVersion(), pri.getSupplements(), pri.getDerivation());
|
||||
this.filename = pri.getFilename();
|
||||
this.loader = loader;
|
||||
}
|
||||
|
|
|
@ -530,6 +530,8 @@ public class TerminologyCache {
|
|||
sw.write(BREAK+"\r\n");
|
||||
if (ce.e != null) {
|
||||
sw.write("e: {\r\n");
|
||||
if (ce.e.isFromServer())
|
||||
sw.write(" \"from-server\" : true,\r\n");
|
||||
if (ce.e.getValueset() != null)
|
||||
sw.write(" \"valueSet\" : "+json.composeString(ce.e.getValueset()).trim()+",\r\n");
|
||||
sw.write(" \"error\" : \""+Utilities.escapeJson(ce.e.getError()).trim()+"\"\r\n}\r\n");
|
||||
|
@ -623,9 +625,9 @@ public class TerminologyCache {
|
|||
String error = loadJS(o.get("error"));
|
||||
if (e) {
|
||||
if (o.has("valueSet"))
|
||||
ce.e = new ValueSetExpansionOutcome((ValueSet) new JsonParser().parse(o.getAsJsonObject("valueSet")), error, TerminologyServiceErrorClass.UNKNOWN);
|
||||
ce.e = new ValueSetExpansionOutcome((ValueSet) new JsonParser().parse(o.getAsJsonObject("valueSet")), error, TerminologyServiceErrorClass.UNKNOWN, o.has("from-server"));
|
||||
else
|
||||
ce.e = new ValueSetExpansionOutcome(error, TerminologyServiceErrorClass.UNKNOWN);
|
||||
ce.e = new ValueSetExpansionOutcome(error, TerminologyServiceErrorClass.UNKNOWN, o.has("from-server"));
|
||||
} else {
|
||||
String t = loadJS(o.get("severity"));
|
||||
IssueSeverity severity = t == null ? null : IssueSeverity.fromCode(t);
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
package org.hl7.fhir.r5.context;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r5.context.CanonicalResourceManager.CanonicalResourceProxy;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
|
||||
public class TypeManager {
|
||||
|
||||
|
||||
private CanonicalResourceManager<StructureDefinition> structures;
|
||||
private Map<String, Set<StructureDefinition>> typeDefinitions = new HashMap<>();
|
||||
private Map<String, Set<StructureDefinition>> fhirTypeDefinitions = new HashMap<>();
|
||||
private Set<String> primitiveNames = new HashSet<>();
|
||||
private Set<String> dataTypeNames = new HashSet<>();
|
||||
|
||||
public TypeManager(CanonicalResourceManager<StructureDefinition> structures) {
|
||||
super();
|
||||
this.structures = structures;
|
||||
reload();
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
typeDefinitions.clear();
|
||||
primitiveNames.clear();
|
||||
dataTypeNames.clear();
|
||||
for (StructureDefinition sd : structures.getList()) {
|
||||
see(sd);
|
||||
}
|
||||
}
|
||||
|
||||
public void see(CanonicalResourceProxy r) {
|
||||
if (!"constraint".equals(r.getDerivation())) {
|
||||
see((StructureDefinition) r.getResource());
|
||||
}
|
||||
}
|
||||
|
||||
public void see(StructureDefinition sd) {
|
||||
if (sd.getDerivation() != TypeDerivationRule.CONSTRAINT) {
|
||||
String type = sd.getType();
|
||||
Set<StructureDefinition> types = typeDefinitions.get(type);
|
||||
if (types == null) {
|
||||
types = new HashSet<>();
|
||||
typeDefinitions.put(type, types);
|
||||
}
|
||||
types.add(sd);
|
||||
if (sd.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition/")) {
|
||||
types = fhirTypeDefinitions.get(type);
|
||||
if (types == null) {
|
||||
types = new HashSet<>();
|
||||
fhirTypeDefinitions.put(type, types);
|
||||
}
|
||||
types.add(sd);
|
||||
}
|
||||
if (sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE) {
|
||||
primitiveNames.add(sd.getType());
|
||||
} else if (sd.getKind() == StructureDefinitionKind.COMPLEXTYPE) {
|
||||
dataTypeNames.add(sd.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<StructureDefinition> getDefinitions(String typeName) {
|
||||
List<StructureDefinition> list = new ArrayList<>();
|
||||
Set<StructureDefinition> defined = typeDefinitions.get(typeName);
|
||||
if (defined != null) {
|
||||
list.addAll(defined);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public StructureDefinition fetchTypeDefinition(String typeName) {
|
||||
Set<StructureDefinition> types = typeDefinitions.get(typeName);
|
||||
if (types == null) {
|
||||
return null; // throw new FHIRException("Unresolved type "+typeName+" (0)");
|
||||
} else if (types.size() == 1) {
|
||||
return types.iterator().next();
|
||||
} else {
|
||||
types = fhirTypeDefinitions.get(typeName);
|
||||
if (types == null) {
|
||||
return null;
|
||||
} else if (types.size() != 1) {
|
||||
throw new FHIRException("Ambiguous type "+typeName+" ("+types.toString()+") (contact Grahame Grieve for investigation)");
|
||||
} else {
|
||||
return types.iterator().next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPrimitive(String type) {
|
||||
if (primitiveNames.contains(type) || Utilities.existsInList(type, "boolean", "integer", "integer64", "string", "decimal", "uri", "base64Binary", "instant", "date", "dateTime", "time", "code", "oid", "id", "markdown", "unsignedInt", "positiveInt", "uuid", "xhtml", "url", "canonical")) {
|
||||
return true;
|
||||
} else {
|
||||
StructureDefinition sd = structures.get(type);
|
||||
return sd != null && sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDataType(String type) {
|
||||
if (dataTypeNames.contains(type) || Utilities.existsInList(type, "Address", "Age", "Annotation", "Attachment", "CodeableConcept", "Coding", "ContactPoint", "Count", "Distance", "Duration", "HumanName", "Identifier", "Money", "Period", "Quantity", "Range", "Ratio", "Reference", "SampledData", "Signature", "Timing",
|
||||
"ContactDetail", "Contributor", "DataRequirement", "Expression", "ParameterDefinition", "RelatedArtifact", "TriggerDefinition", "UsageContext")) {
|
||||
return true;
|
||||
} else {
|
||||
StructureDefinition sd = structures.get(type);
|
||||
return sd != null && sd.getKind() == StructureDefinitionKind.COMPLEXTYPE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -556,7 +556,7 @@ public class Element extends Base {
|
|||
return ne;
|
||||
} else if (p.getDefinition().isChoice() && name.startsWith(p.getName().replace("[x]", ""))) {
|
||||
String type = name.substring(p.getName().length()-3);
|
||||
if (new ContextUtilities(property.getContext()).isPrimitiveDatatype(Utilities.uncapitalize(type))) {
|
||||
if (property.getContext().isPrimitiveType(Utilities.uncapitalize(type))) {
|
||||
type = Utilities.uncapitalize(type);
|
||||
}
|
||||
Element ne = new Element(name, p);
|
||||
|
@ -1335,7 +1335,7 @@ public class Element extends Base {
|
|||
|
||||
for (Property p : property.getChildProperties(this.name, type)) {
|
||||
if (p.getName().equals(name)) {
|
||||
if (!p.isList()) {
|
||||
if (!p.isList() && hasChild(name)) {
|
||||
throw new Error(name+" on "+this.name+" is not a list, so can't add an element");
|
||||
}
|
||||
Element ne = new Element(name, p);
|
||||
|
|
|
@ -45,12 +45,12 @@ public class FmlParser extends ParserBase {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<NamedElement> parse(InputStream inStream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||
public List<ValidatedFragment> parse(InputStream inStream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||
byte[] content = TextFile.streamToBytes(inStream);
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||
String text = TextFile.streamToString(stream);
|
||||
List<NamedElement> result = new ArrayList<>();
|
||||
NamedElement ctxt = new NamedElement("focus", "fml", content);
|
||||
List<ValidatedFragment> result = new ArrayList<>();
|
||||
ValidatedFragment ctxt = new ValidatedFragment("focus", "fml", content);
|
||||
ctxt.setElement(parse(ctxt.getErrors(), text));
|
||||
result.add(ctxt);
|
||||
return result;
|
||||
|
@ -571,7 +571,9 @@ public class FmlParser extends ParserBase {
|
|||
private void parseParameter(Element ref, FHIRLexer lexer) throws FHIRLexerException, FHIRFormatError {
|
||||
boolean r5 = VersionUtilities.isR5Plus(context.getVersion());
|
||||
String name = r5 ? "parameter" : "variable";
|
||||
if (!lexer.isConstant()) {
|
||||
if (ref.hasChildren(name) && !ref.getChildByName(name).isList()) {
|
||||
throw lexer.error("variable on target is not a list, so can't add an element");
|
||||
} else if (!lexer.isConstant()) {
|
||||
ref.addElement(name).markLocation(lexer.getCurrentLocation()).makeElement(r5 ? "valueId" : "value").setValue(lexer.take());
|
||||
} else if (lexer.isStringConstant())
|
||||
ref.addElement(name).markLocation(lexer.getCurrentLocation()).makeElement(r5 ? "valueString" : "value").setValue(lexer.readConstant("??"));
|
||||
|
|
|
@ -52,7 +52,6 @@ import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
|||
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.elementmodel.Element.SpecialElement;
|
||||
import org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.formats.JsonCreator;
|
||||
import org.hl7.fhir.r5.formats.JsonCreatorCanonical;
|
||||
|
@ -120,10 +119,10 @@ public class JsonParser extends ParserBase {
|
|||
|
||||
|
||||
@Override
|
||||
public List<NamedElement> parse(InputStream inStream) throws IOException, FHIRException {
|
||||
long start = System.currentTimeMillis();
|
||||
public List<ValidatedFragment> parse(InputStream inStream) throws IOException, FHIRException {
|
||||
// long start = System.currentTimeMillis();
|
||||
byte[] content = TextFile.streamToBytes(inStream);
|
||||
NamedElement ctxt = new NamedElement("focus", "json", content);
|
||||
ValidatedFragment ctxt = new ValidatedFragment("focus", "json", content);
|
||||
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||
|
||||
|
@ -141,16 +140,21 @@ public class JsonParser extends ParserBase {
|
|||
obj = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(source, true, true);
|
||||
}
|
||||
|
||||
if (obj != null) {
|
||||
ctxt.setElement(parse(ctxt.getErrors(), obj));
|
||||
List<NamedElement> res = new ArrayList<>();
|
||||
}
|
||||
List<ValidatedFragment> res = new ArrayList<>();
|
||||
res.add(ctxt);
|
||||
|
||||
long t=System.currentTimeMillis()-start;
|
||||
System.out.println("json parser: "+(t)+"ms, "+(content.length/1024)+"kb "+(t == 0 ? "" : " @ "+(content.length / t)+"kb/s"));
|
||||
// long t =System.currentTimeMillis()-start;
|
||||
// System.out.println("json parser: "+(t)+"ms, "+(content.length/1024)+"kb "+(t == 0 ? "" : " @ "+(content.length / t)+"kb/s"));
|
||||
return res;
|
||||
}
|
||||
|
||||
public Element parse(List<ValidationMessage> errors, JsonObject object) throws FHIRException {
|
||||
if (object == null) {
|
||||
System.out.println("What?");
|
||||
}
|
||||
StructureDefinition sd = getLogical();
|
||||
String name;
|
||||
String path;
|
||||
|
|
|
@ -41,7 +41,6 @@ import org.hl7.fhir.exceptions.FHIRException;
|
|||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
||||
import org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
|
||||
|
@ -106,7 +105,7 @@ public class Manager {
|
|||
}
|
||||
}
|
||||
|
||||
public static List<NamedElement> parse(IWorkerContext context, InputStream source, FhirFormat inputFormat) throws FHIRFormatError, DefinitionException, IOException, FHIRException {
|
||||
public static List<ValidatedFragment> parse(IWorkerContext context, InputStream source, FhirFormat inputFormat) throws FHIRFormatError, DefinitionException, IOException, FHIRException {
|
||||
return makeParser(context, inputFormat).parse(source);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ import org.hl7.fhir.exceptions.FHIRException;
|
|||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.SourcedChildDefinitions;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||
|
@ -72,7 +71,7 @@ public class ObjectConverter {
|
|||
org.hl7.fhir.r5.formats.JsonParser jp = new org.hl7.fhir.r5.formats.JsonParser();
|
||||
jp.compose(bs, ig);
|
||||
ByteArrayInputStream bi = new ByteArrayInputStream(bs.toByteArray());
|
||||
List<NamedElement> list = new JsonParser(context).parse(bi);
|
||||
List<ValidatedFragment> list = new JsonParser(context).parse(bi);
|
||||
if (list.size() != 1) {
|
||||
throw new FHIRException("Unable to convert because the source contains multieple resources");
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
|
@ -69,54 +68,6 @@ public abstract class ParserBase {
|
|||
}
|
||||
}
|
||||
|
||||
public class NamedElement {
|
||||
private String name;
|
||||
private String extension;
|
||||
private Element element;
|
||||
private byte[] content;
|
||||
private List<ValidationMessage> errors = new ArrayList<>();
|
||||
|
||||
public NamedElement(String name, String extension, Element element, byte[] content) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.element = element;
|
||||
this.content = content;
|
||||
this.extension = extension;
|
||||
}
|
||||
|
||||
public NamedElement(String name, String extension, byte[] content) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.content = content;
|
||||
this.extension = extension;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Element getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public byte[] getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public List<ValidationMessage> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
public void setElement(Element element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public String getFilename() {
|
||||
return name+"."+extension;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface ILinkResolver {
|
||||
String resolveType(String type);
|
||||
String resolveProperty(Property property);
|
||||
|
@ -126,13 +77,7 @@ public abstract class ParserBase {
|
|||
public enum ValidationPolicy { NONE, QUICK, EVERYTHING }
|
||||
|
||||
public boolean isPrimitive(String code) {
|
||||
StructureDefinition sd = context.fetchTypeDefinition(code);
|
||||
if (sd != null) {
|
||||
return sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE;
|
||||
}
|
||||
|
||||
return Utilities.existsInList(code, "boolean", "integer", "integer64", "string", "decimal", "uri", "base64Binary", "instant", "date", "dateTime", "time", "code", "oid", "id", "markdown", "unsignedInt", "positiveInt", "uuid", "xhtml", "url", "canonical");
|
||||
|
||||
return context.isPrimitiveType(code);
|
||||
}
|
||||
|
||||
protected IWorkerContext context;
|
||||
|
@ -152,20 +97,20 @@ public abstract class ParserBase {
|
|||
this.policy = policy;
|
||||
}
|
||||
|
||||
public abstract List<NamedElement> parse(InputStream stream) throws IOException, FHIRFormatError, DefinitionException, FHIRException;
|
||||
public abstract List<ValidatedFragment> parse(InputStream stream) throws IOException, FHIRFormatError, DefinitionException, FHIRException;
|
||||
|
||||
public Element parseSingle(InputStream stream, List<ValidationMessage> errors) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||
|
||||
List<NamedElement> res = parse(stream);
|
||||
List<ValidatedFragment> res = parse(stream);
|
||||
|
||||
if (res.size() != 1) {
|
||||
throw new FHIRException("Parsing FHIR content returned multiple elements in a context where only one element is allowed");
|
||||
}
|
||||
var resE = res.get(0);
|
||||
if (resE.getElement() == null) {
|
||||
throw new FHIRException("Parsing FHIR content failed: "+errorSummary(resE.errors));
|
||||
throw new FHIRException("Parsing FHIR content failed: "+errorSummary(resE.getErrors()));
|
||||
} else if (res.size() == 0) {
|
||||
throw new FHIRException("Parsing FHIR content returned no elements in a context where one element is required because: "+errorSummary(resE.errors));
|
||||
throw new FHIRException("Parsing FHIR content returned no elements in a context where one element is required because: "+errorSummary(resE.getErrors()));
|
||||
}
|
||||
if (errors != null) {
|
||||
errors.addAll(resE.getErrors());
|
||||
|
|
|
@ -249,12 +249,7 @@ public class Property {
|
|||
* @param E.g. "integer"
|
||||
*/
|
||||
public boolean isPrimitive(String code) {
|
||||
if (Utilities.isAbsoluteUrl(code)) {
|
||||
StructureDefinition sd = context.fetchTypeDefinition(code);
|
||||
return sd != null && sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE;
|
||||
} else {
|
||||
return TypesUtilities.isPrimitive(code);
|
||||
}
|
||||
return context.isPrimitiveType(code);
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
|
|
|
@ -27,7 +27,7 @@ public class ResourceParser extends ParserBase {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<NamedElement> parse(InputStream stream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||
public List<ValidatedFragment> parse(InputStream stream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||
throw new NotImplementedException("parse(InputStream stream)"); // doesns't make sense
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import org.hl7.fhir.exceptions.DefinitionException;
|
|||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement;
|
||||
import org.hl7.fhir.r5.elementmodel.SHCParser.SHCSignedJWT;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.utilities.TextFile;
|
||||
|
@ -80,11 +79,11 @@ public class SHCParser extends ParserBase {
|
|||
jsonParser = new JsonParser(context);
|
||||
}
|
||||
|
||||
public List<NamedElement> parse(InputStream inStream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||
public List<ValidatedFragment> parse(InputStream inStream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||
byte[] content = TextFile.streamToBytes(inStream);
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||
List<NamedElement> res = new ArrayList<>();
|
||||
NamedElement shc = new NamedElement("shc", "json", content);
|
||||
List<ValidatedFragment> res = new ArrayList<>();
|
||||
ValidatedFragment shc = new ValidatedFragment("shc", "json", content);
|
||||
res.add(shc);
|
||||
|
||||
String src = TextFile.streamToString(stream).trim();
|
||||
|
@ -166,7 +165,7 @@ public class SHCParser extends ParserBase {
|
|||
return res;
|
||||
}
|
||||
// ok. all checks passed, we can now validate the bundle
|
||||
NamedElement bnd = new NamedElement(path, "json", org.hl7.fhir.utilities.json.parser.JsonParser.composeBytes(cs.getJsonObject("fhirBundle")));
|
||||
ValidatedFragment bnd = new ValidatedFragment(path, "json", org.hl7.fhir.utilities.json.parser.JsonParser.composeBytes(cs.getJsonObject("fhirBundle")));
|
||||
res.add(bnd);
|
||||
bnd.setElement(jsonParser.parse(bnd.getErrors(), cs.getJsonObject("fhirBundle")));
|
||||
}
|
||||
|
|
|
@ -72,11 +72,11 @@ public class SHLParser extends ParserBase {
|
|||
super(context);
|
||||
}
|
||||
|
||||
public List<NamedElement> parse(InputStream inStream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||
public List<ValidatedFragment> parse(InputStream inStream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||
byte[] content = TextFile.streamToBytes(inStream);
|
||||
|
||||
List<NamedElement> res = new ArrayList<>();
|
||||
NamedElement shl = addNamedElement(res, "shl", "txt", content);
|
||||
List<ValidatedFragment> res = new ArrayList<>();
|
||||
ValidatedFragment shl = addNamedElement(res, "shl", "txt", content);
|
||||
String src = TextFile.bytesToString(content);
|
||||
|
||||
if (src.startsWith("shlink:/")) {
|
||||
|
@ -93,7 +93,7 @@ public class SHLParser extends ParserBase {
|
|||
}
|
||||
if (src != null) {
|
||||
byte[] cntin = Base64.getUrlDecoder().decode(src);
|
||||
NamedElement json = addNamedElement(res, "json", "json", cntin);
|
||||
ValidatedFragment json = addNamedElement(res, "json", "json", cntin);
|
||||
JsonObject j = null;
|
||||
try {
|
||||
j = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(cntin);
|
||||
|
@ -145,8 +145,8 @@ public class SHLParser extends ParserBase {
|
|||
}
|
||||
|
||||
|
||||
private void checkManifest(List<NamedElement> res, HTTPResult cnt) throws IOException {
|
||||
NamedElement manifest = addNamedElement(res, "manifest", "json", cnt.getContent());
|
||||
private void checkManifest(List<ValidatedFragment> res, HTTPResult cnt) throws IOException {
|
||||
ValidatedFragment manifest = addNamedElement(res, "manifest", "json", cnt.getContent());
|
||||
|
||||
if (!cnt.getContentType().equals("application/json")) {
|
||||
logError(manifest.getErrors(), "202-08-31", 1, 1, "manifest", IssueType.STRUCTURE, "The mime type should be application/json not "+cnt.getContentType(), IssueSeverity.ERROR);
|
||||
|
@ -188,7 +188,7 @@ public class SHLParser extends ParserBase {
|
|||
}
|
||||
}
|
||||
|
||||
private void processManifestEntry(List<NamedElement> res, List<ValidationMessage> errors, JsonObject j, String path, String name) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
||||
private void processManifestEntry(List<ValidatedFragment> res, List<ValidationMessage> errors, JsonObject j, String path, String name) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
||||
for (JsonProperty p : j.getProperties()) {
|
||||
if (!Utilities.existsInList(p.getName(), "contentType", "location", "embedded")) {
|
||||
logError(errors, "202-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "manifest."+p.getName(),
|
||||
|
@ -242,8 +242,8 @@ public class SHLParser extends ParserBase {
|
|||
}
|
||||
}
|
||||
|
||||
private void processContent(List<NamedElement> res, List<ValidationMessage> errors, String path, String name, String jose, String ct) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
||||
NamedElement bin = addNamedElement(res, "encrypted", "jose", TextFile.stringToBytes(jose, false));
|
||||
private void processContent(List<ValidatedFragment> res, List<ValidationMessage> errors, String path, String name, String jose, String ct) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
||||
ValidatedFragment bin = addNamedElement(res, "encrypted", "jose", TextFile.stringToBytes(jose, false));
|
||||
byte[] cnt = null;
|
||||
JWEObject jwe;
|
||||
try {
|
||||
|
@ -261,7 +261,7 @@ public class SHLParser extends ParserBase {
|
|||
res.addAll(shc.parse(new ByteArrayInputStream(cnt)));
|
||||
break;
|
||||
case "application/fhir+json":
|
||||
NamedElement doc = addNamedElement(res, name, "json", cnt);
|
||||
ValidatedFragment doc = addNamedElement(res, name, "json", cnt);
|
||||
// a JSON file containing any FHIR resource (e.g., an individual resource or a Bundle of resources). Generally this format may not be tamper-proof.
|
||||
logError(doc.getErrors(), "202-08-31", 1, 1, name, IssueType.STRUCTURE, "Processing content of type 'application/smart-api-access' is not done yet", IssueSeverity.INFORMATION);
|
||||
break;
|
||||
|
@ -279,8 +279,8 @@ public class SHLParser extends ParserBase {
|
|||
}
|
||||
}
|
||||
|
||||
private NamedElement addNamedElement(List<NamedElement> res, String name, String type, byte[] content) {
|
||||
NamedElement result = new NamedElement(name, type, content);
|
||||
private ValidatedFragment addNamedElement(List<ValidatedFragment> res, String name, String type, byte[] content) {
|
||||
ValidatedFragment result = new ValidatedFragment(name, type, content);
|
||||
res.add(result);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ import org.hl7.fhir.exceptions.FHIRException;
|
|||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||
import org.hl7.fhir.r5.elementmodel.Element.SpecialElement;
|
||||
import org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement;
|
||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
|
@ -81,9 +80,9 @@ public class TurtleParser extends ParserBase {
|
|||
super(context);
|
||||
}
|
||||
@Override
|
||||
public List<NamedElement> parse(InputStream inStream) throws IOException, FHIRException {
|
||||
public List<ValidatedFragment> parse(InputStream inStream) throws IOException, FHIRException {
|
||||
byte[] content = TextFile.streamToBytes(inStream);
|
||||
NamedElement ctxt = new NamedElement("focus", "ttl", content);
|
||||
ValidatedFragment ctxt = new ValidatedFragment("focus", "ttl", content);
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||
|
||||
Turtle src = new Turtle();
|
||||
|
@ -99,7 +98,7 @@ public class TurtleParser extends ParserBase {
|
|||
src.parse(TextFile.streamToString(stream));
|
||||
ctxt.setElement(parse(ctxt.getErrors(), src));
|
||||
}
|
||||
List<NamedElement> res = new ArrayList<>();
|
||||
List<ValidatedFragment> res = new ArrayList<>();
|
||||
res.add(ctxt);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package org.hl7.fhir.r5.elementmodel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
|
||||
public class ValidatedFragment {
|
||||
private String name;
|
||||
private String extension;
|
||||
private Element element;
|
||||
private byte[] content;
|
||||
private List<ValidationMessage> errors = new ArrayList<>();
|
||||
|
||||
public ValidatedFragment(String name, String extension, Element element, byte[] content) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.element = element;
|
||||
this.content = content;
|
||||
this.extension = extension;
|
||||
}
|
||||
|
||||
public ValidatedFragment(String name, String extension, byte[] content) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.content = content;
|
||||
this.extension = extension;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Element getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public byte[] getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public List<ValidationMessage> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
public void setElement(Element element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public String getFilename() {
|
||||
return name+"."+extension;
|
||||
}
|
||||
|
||||
}
|
|
@ -454,7 +454,7 @@ public class VerticalBarParser extends ParserBase {
|
|||
private Delimiters delimiters = new Delimiters();
|
||||
|
||||
@Override
|
||||
public List<NamedElement> parse(InputStream inStream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||
public List<ValidatedFragment> parse(InputStream inStream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/v2/StructureDefinition/Message");
|
||||
Element message = new Element("Message", new Property(context, sd.getSnapshot().getElementFirstRep(), sd));
|
||||
byte[] content = TextFile.streamToBytes(inStream);
|
||||
|
@ -464,8 +464,8 @@ public class VerticalBarParser extends ParserBase {
|
|||
preDecode(reader);
|
||||
while (!reader.isFinished()) // && (getOptions().getSegmentLimit() == 0 || getOptions().getSegmentLimit() > message.getSegments().size()))
|
||||
readSegment(message, reader);
|
||||
List<NamedElement> res = new ArrayList<>();
|
||||
res.add(new NamedElement("focus", "hl7", message, content));
|
||||
List<ValidatedFragment> res = new ArrayList<>();
|
||||
res.add(new ValidatedFragment("focus", "hl7", message, content));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -111,10 +111,10 @@ public class XmlParser extends ParserBase {
|
|||
this.allowXsiLocation = allowXsiLocation;
|
||||
}
|
||||
|
||||
public List<NamedElement> parse(InputStream inStream) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
||||
public List<ValidatedFragment> parse(InputStream inStream) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
||||
|
||||
byte[] content = TextFile.streamToBytes(inStream);
|
||||
NamedElement context = new NamedElement("focus", "xml", content);
|
||||
ValidatedFragment context = new ValidatedFragment("focus", "xml", content);
|
||||
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||
Document doc = null;
|
||||
|
@ -177,7 +177,7 @@ public class XmlParser extends ParserBase {
|
|||
if (doc != null) {
|
||||
context.setElement(parse(context.getErrors(), doc));
|
||||
}
|
||||
List<NamedElement> res = new ArrayList<>();
|
||||
List<ValidatedFragment> res = new ArrayList<>();
|
||||
res.add(context);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -323,7 +323,7 @@ public class PEBuilder {
|
|||
if (passElementPropsCheck(defn) && !Utilities.existsInList(defn.getName(), omitList)) {
|
||||
PEDefinitionElement pe = new PEDefinitionElement(this, profile, defn, parent.path());
|
||||
pe.setRecursing(definition == defn || (profile.getDerivation() == TypeDerivationRule.SPECIALIZATION && profile.getType().equals("Extension")));
|
||||
if (cu.isPrimitiveDatatype(definition.getTypeFirstRep().getWorkingCode()) && "value".equals(pe.name())) {
|
||||
if (context.isPrimitiveType(definition.getTypeFirstRep().getWorkingCode()) && "value".equals(pe.name())) {
|
||||
pe.setMustHaveValue(definition.getMustHaveValue());
|
||||
}
|
||||
pe.setInFixedValue(definition.hasFixed() || definition.hasPattern() || parent.isInFixedValue());
|
||||
|
|
|
@ -111,6 +111,7 @@ public class LiquidRenderer extends ResourceRenderer implements ILiquidRendering
|
|||
LiquidEngine engine = new LiquidEngine(context.getWorker(), context.getServices());
|
||||
XhtmlNode xn;
|
||||
try {
|
||||
engine.setIncludeResolver(new LiquidRendererIncludeResolver(context));
|
||||
LiquidDocument doc = engine.parse(liquidTemplate, "template");
|
||||
engine.setRenderingSupport(this);
|
||||
String html = engine.evaluate(doc, r.getBase(), new LiquidRendererContxt(rcontext, r));
|
||||
|
|
|
@ -801,7 +801,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
|||
}
|
||||
} else if (hasDef && element.getType().get(0).getWorkingCode() != null && element.getType().get(0).getWorkingCode().startsWith("@")) {
|
||||
row.setIcon("icon_reuse.png", HierarchicalTableGenerator.TEXT_ICON_REUSE);
|
||||
} else if (hasDef && isPrimitive(element.getType().get(0).getWorkingCode())) {
|
||||
} else if (hasDef && context.getContext().isPrimitiveType(element.getType().get(0).getWorkingCode())) {
|
||||
if (keyRows.contains(element.getId())) {
|
||||
row.setIcon("icon-key.png", HierarchicalTableGenerator.TEXT_ICON_KEY);
|
||||
} else {
|
||||
|
@ -809,7 +809,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
|||
}
|
||||
} else if (hasDef && element.getType().get(0).hasTarget()) {
|
||||
row.setIcon("icon_reference.png", HierarchicalTableGenerator.TEXT_ICON_REFERENCE);
|
||||
} else if (hasDef && isDataType(element.getType().get(0).getWorkingCode())) {
|
||||
} else if (hasDef && context.getContext().isDataType(element.getType().get(0).getWorkingCode())) {
|
||||
row.setIcon("icon_datatype.gif", HierarchicalTableGenerator.TEXT_ICON_DATATYPE);
|
||||
} else if (hasDef && element.hasExtension(ToolingExtensions.EXT_JSON_PROP_KEY)) {
|
||||
row.setIcon("icon-object-box.png", HierarchicalTableGenerator.TEXT_ICON_OBJECT_BOX);
|
||||
|
@ -1309,7 +1309,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
|||
boolean first = true;
|
||||
for (StructureDefinition sd : children) {
|
||||
if (first) first = false; else c.addPiece(gen.new Piece(null, ", ", null));
|
||||
c.addPiece(gen.new Piece(sd.getWebPath(), sd.getTypeName(), null));
|
||||
c.addPiece(gen.new Piece(sd.getWebPath(), sd.getName(), null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2122,7 +2122,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
|||
if (!pattern) {
|
||||
c.addPiece(gen.new Piece(null, "0..0", null));
|
||||
row.setIcon("icon_fixed.gif", "Fixed Value" /*HierarchicalTableGenerator.TEXT_ICON_FIXED*/);
|
||||
} else if (isPrimitive(t.getTypeCode())) {
|
||||
} else if (context.getContext().isPrimitiveType(t.getTypeCode())) {
|
||||
row.setIcon("icon_primitive.png", HierarchicalTableGenerator.TEXT_ICON_PRIMITIVE);
|
||||
c.addPiece(gen.new Piece(null, "0.."+(t.getMaxCardinality() == 2147483647 ? "*": Integer.toString(t.getMaxCardinality())), null));
|
||||
} else if (isReference(t.getTypeCode())) {
|
||||
|
@ -2450,28 +2450,6 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
|||
return path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected boolean isPrimitive(String value) {
|
||||
StructureDefinition sd = context.getWorker().fetchTypeDefinition(value);
|
||||
if (sd == null) // might be running before all SDs are available
|
||||
return Utilities.existsInList(value, "base64Binary", "boolean", "canonical", "code", "date", "dateTime", "decimal", "id", "instant", "integer", "integer64", "markdown", "oid", "positiveInt", "string", "time", "unsignedInt", "uri", "url", "uuid");
|
||||
else
|
||||
return sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE;
|
||||
}
|
||||
|
||||
|
||||
private boolean isDataType(String value) {
|
||||
StructureDefinition sd = context.getWorker().fetchTypeDefinition(value);
|
||||
if (sd == null) // might be running before all SDs are available
|
||||
return Utilities.existsInList(value, "Address", "Age", "Annotation", "Attachment", "CodeableConcept", "Coding", "ContactPoint", "Count", "Distance", "Duration", "HumanName", "Identifier", "Money", "Period", "Quantity", "Range", "Ratio", "Reference", "SampledData", "Signature", "Timing",
|
||||
"ContactDetail", "Contributor", "DataRequirement", "Expression", "ParameterDefinition", "RelatedArtifact", "TriggerDefinition", "UsageContext");
|
||||
else
|
||||
return sd.getKind() == StructureDefinitionKind.COMPLEXTYPE && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION;
|
||||
}
|
||||
|
||||
private boolean slicesExist(List<ElementDefinition> elements, ElementDefinition element) {
|
||||
if (elements == null) {
|
||||
return true;
|
||||
|
@ -3827,7 +3805,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer {
|
|||
|
||||
private boolean hasPrimitiveTypes(ElementDefinition d) {
|
||||
for (TypeRefComponent tr : d.getType()) {
|
||||
if (isPrimitive(tr.getCode())) {
|
||||
if (context.getContext().isPrimitiveType(tr.getCode())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,10 @@ import org.hl7.fhir.exceptions.FHIRException;
|
|||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
import org.hl7.fhir.exceptions.TerminologyServiceException;
|
||||
import org.hl7.fhir.r5.comparison.VersionComparisonAnnotation;
|
||||
import org.hl7.fhir.r5.context.TerminologyCache;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.CodingValidationRequest;
|
||||
import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult;
|
||||
import org.hl7.fhir.r5.context.TerminologyCache.CacheToken;
|
||||
import org.hl7.fhir.r5.model.Base;
|
||||
import org.hl7.fhir.r5.model.BooleanType;
|
||||
import org.hl7.fhir.r5.model.CanonicalResource;
|
||||
|
@ -26,8 +28,10 @@ import org.hl7.fhir.r5.model.Coding;
|
|||
import org.hl7.fhir.r5.model.ConceptMap;
|
||||
import org.hl7.fhir.r5.model.DataType;
|
||||
import org.hl7.fhir.r5.model.Enumerations.FilterOperator;
|
||||
import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
|
||||
import org.hl7.fhir.r5.model.Extension;
|
||||
import org.hl7.fhir.r5.model.ExtensionHelper;
|
||||
import org.hl7.fhir.r5.model.Parameters;
|
||||
import org.hl7.fhir.r5.model.PrimitiveType;
|
||||
import org.hl7.fhir.r5.model.Resource;
|
||||
import org.hl7.fhir.r5.model.StringType;
|
||||
|
@ -38,6 +42,7 @@ import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent;
|
|||
import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceDesignationComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetComposeComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent;
|
||||
|
@ -48,9 +53,11 @@ import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
|||
import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
|
||||
import org.hl7.fhir.r5.terminologies.ValueSetUtilities;
|
||||
import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome;
|
||||
import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.utilities.LoincLinker;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
|
||||
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Row;
|
||||
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.TableModel;
|
||||
|
@ -1142,7 +1149,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean genInclude(XhtmlNode ul, ConceptSetComponent inc, String type, List<String> langs, boolean doDesignations, List<UsedConceptMap> maps, Map<String, String> designations, int index, Resource vsRes) throws FHIRException, IOException {
|
||||
private boolean genInclude(XhtmlNode ul, ConceptSetComponent inc, String type, List<String> langs, boolean doDesignations, List<UsedConceptMap> maps, Map<String, String> designations, int index, ValueSet vsRes) throws FHIRException, IOException {
|
||||
boolean hasExtensions = false;
|
||||
XhtmlNode li;
|
||||
li = ul.li();
|
||||
|
@ -1165,7 +1172,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
}
|
||||
|
||||
// for performance reasons, we do all the fetching in one batch
|
||||
definitions = getConceptsForCodes(e, inc);
|
||||
definitions = getConceptsForCodes(e, inc, vsRes, index);
|
||||
|
||||
|
||||
XhtmlNode t = li.table("none");
|
||||
|
@ -1361,7 +1368,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
}
|
||||
|
||||
|
||||
private Map<String, ConceptDefinitionComponent> getConceptsForCodes(CodeSystem e, ConceptSetComponent inc) {
|
||||
private Map<String, ConceptDefinitionComponent> getConceptsForCodes(CodeSystem e, ConceptSetComponent inc, ValueSet source, int index) {
|
||||
if (e == null) {
|
||||
e = getContext().getWorker().fetchCodeSystem(inc.getSystem());
|
||||
}
|
||||
|
@ -1369,13 +1376,21 @@ public class ValueSetRenderer extends TerminologyRenderer {
|
|||
ValueSetExpansionComponent vse = null;
|
||||
if (!context.isNoSlowLookup()) { // && !getContext().getWorker().hasCache()) { removed GG 20220107 like what is this trying to do?
|
||||
try {
|
||||
ValueSetExpansionOutcome vso = getContext().getWorker().expandVS(inc, false, false);
|
||||
|
||||
ValueSet vs = new ValueSet();
|
||||
vs.setUrl(source.getUrl()+"-inc-"+index);
|
||||
vs.setStatus(PublicationStatus.ACTIVE);
|
||||
vs.setCompose(new ValueSetComposeComponent());
|
||||
vs.getCompose().setInactive(false);
|
||||
vs.getCompose().getInclude().add(inc);
|
||||
|
||||
ValueSetExpansionOutcome vso = getContext().getWorker().expandVS(vs, true, false);
|
||||
ValueSet valueset = vso.getValueset();
|
||||
if (valueset == null)
|
||||
throw new TerminologyServiceException("Error Expanding ValueSet: "+vso.getError());
|
||||
vse = valueset.getExpansion();
|
||||
|
||||
} catch (TerminologyServiceException e1) {
|
||||
} catch (Exception e1) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,6 +123,7 @@ import org.hl7.fhir.r5.terminologies.utilities.TerminologyOperationContext.Termi
|
|||
import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass;
|
||||
import org.hl7.fhir.r5.terminologies.utilities.ValueSetProcessBase;
|
||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||
import org.hl7.fhir.r5.utils.client.EFhirClientException;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.i18n.AcceptLanguageHeader;
|
||||
|
@ -582,23 +583,23 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
} catch (NoTerminologyServiceException e) {
|
||||
// well, we couldn't expand, so we'll return an interface to a checker that can check membership of the set
|
||||
// that might fail too, but it might not, later.
|
||||
return new ValueSetExpansionOutcome(e.getMessage(), TerminologyServiceErrorClass.NOSERVICE, allErrors);
|
||||
return new ValueSetExpansionOutcome(e.getMessage(), TerminologyServiceErrorClass.NOSERVICE, allErrors, false);
|
||||
} catch (CodeSystemProviderExtension e) {
|
||||
// well, we couldn't expand, so we'll return an interface to a checker that can check membership of the set
|
||||
// that might fail too, but it might not, later.
|
||||
return new ValueSetExpansionOutcome(e.getMessage(), TerminologyServiceErrorClass.INTERNAL_ERROR, allErrors);
|
||||
return new ValueSetExpansionOutcome(e.getMessage(), TerminologyServiceErrorClass.INTERNAL_ERROR, allErrors, false);
|
||||
} catch (TerminologyServiceProtectionException e) {
|
||||
if (opContext.isOriginal()) {
|
||||
return new ValueSetExpansionOutcome(e.getMessage(), e.getError(), allErrors);
|
||||
return new ValueSetExpansionOutcome(e.getMessage(), e.getError(), allErrors, false);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
} catch (ETooCostly e) {
|
||||
return new ValueSetExpansionOutcome(e.getMessage(), TerminologyServiceErrorClass.TOO_COSTLY, allErrors);
|
||||
return new ValueSetExpansionOutcome(e.getMessage(), TerminologyServiceErrorClass.TOO_COSTLY, allErrors, false);
|
||||
} catch (Exception e) {
|
||||
// well, we couldn't expand, so we'll return an interface to a checker that can check membership of the set
|
||||
// that might fail too, but it might not, later.
|
||||
return new ValueSetExpansionOutcome(e.getMessage(), TerminologyServiceErrorClass.UNKNOWN, allErrors);
|
||||
return new ValueSetExpansionOutcome(e.getMessage(), TerminologyServiceErrorClass.UNKNOWN, allErrors, e instanceof EFhirClientException || e instanceof TerminologyServiceException);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -705,7 +706,7 @@ public class ValueSetExpander extends ValueSetProcessBase {
|
|||
focus.getExpansion().setTotal(dwc.getTotal());
|
||||
}
|
||||
if (!requiredSupplements.isEmpty()) {
|
||||
return new ValueSetExpansionOutcome(context.formatMessagePlural(requiredSupplements.size(), I18nConstants.VALUESET_SUPPLEMENT_MISSING, CommaSeparatedStringBuilder.build(requiredSupplements)), TerminologyServiceErrorClass.BUSINESS_RULE, allErrors);
|
||||
return new ValueSetExpansionOutcome(context.formatMessagePlural(requiredSupplements.size(), I18nConstants.VALUESET_SUPPLEMENT_MISSING, CommaSeparatedStringBuilder.build(requiredSupplements)), TerminologyServiceErrorClass.BUSINESS_RULE, allErrors, false);
|
||||
}
|
||||
if (!expParams.hasParameter("includeDefinition") || !expParams.getParameterBool("includeDefinition")) {
|
||||
focus.setCompose(null);
|
||||
|
|
|
@ -19,30 +19,34 @@ public class ValueSetExpansionOutcome {
|
|||
private TerminologyServiceErrorClass errorClass;
|
||||
private String txLink;
|
||||
private List<String> allErrors = new ArrayList<>();
|
||||
private boolean fromServer;
|
||||
|
||||
public ValueSetExpansionOutcome(ValueSet valueset) {
|
||||
super();
|
||||
this.valueset = valueset;
|
||||
this.error = null;
|
||||
}
|
||||
public ValueSetExpansionOutcome(ValueSet valueset, String error, TerminologyServiceErrorClass errorClass) {
|
||||
public ValueSetExpansionOutcome(ValueSet valueset, String error, TerminologyServiceErrorClass errorClass, boolean fromServer) {
|
||||
super();
|
||||
this.valueset = valueset;
|
||||
this.error = error;
|
||||
this.errorClass = errorClass;
|
||||
this.fromServer = fromServer;
|
||||
allErrors.add(error);
|
||||
}
|
||||
|
||||
public ValueSetExpansionOutcome(String error, TerminologyServiceErrorClass errorClass) {
|
||||
public ValueSetExpansionOutcome(String error, TerminologyServiceErrorClass errorClass, boolean fromServer) {
|
||||
this.valueset = null;
|
||||
this.error = error;
|
||||
this.errorClass = errorClass;
|
||||
this.fromServer = fromServer;
|
||||
allErrors.add(error);
|
||||
}
|
||||
public ValueSetExpansionOutcome(String error, TerminologyServiceErrorClass errorClass, List<String> errList) {
|
||||
public ValueSetExpansionOutcome(String error, TerminologyServiceErrorClass errorClass, List<String> errList, boolean fromServer) {
|
||||
this.valueset = null;
|
||||
this.error = error;
|
||||
this.errorClass = errorClass;
|
||||
this.fromServer = fromServer;
|
||||
this.allErrors.addAll(errList);
|
||||
if (!allErrors.contains(error)) {
|
||||
allErrors.add(error);
|
||||
|
@ -72,6 +76,9 @@ public class ValueSetExpansionOutcome {
|
|||
return allErrors;
|
||||
}
|
||||
|
||||
public boolean isFromServer() {
|
||||
return fromServer;
|
||||
}
|
||||
public boolean isOk() {
|
||||
return (allErrors.isEmpty() || (allErrors.size() == 1 && allErrors.get(0) == null)) && error == null;
|
||||
}
|
||||
|
|
|
@ -451,7 +451,13 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
|
||||
@Override
|
||||
public void evaluate(StringBuilder b, Base resource, LiquidEngineContext ctxt) throws FHIRException {
|
||||
if (includeResolver == null) {
|
||||
throw new FHIRException("Includes are not supported in this context");
|
||||
}
|
||||
String src = includeResolver.fetchInclude(LiquidEngine.this, page);
|
||||
if (src == null) {
|
||||
throw new FHIRException("The include '"+page+"' could not be resolved");
|
||||
}
|
||||
LiquidParser parser = new LiquidParser(src);
|
||||
LiquidDocument doc = parser.parse(page);
|
||||
LiquidEngineContext nctxt = new LiquidEngineContext(ctxt.externalContext, ctxt);
|
||||
|
@ -617,8 +623,8 @@ public class LiquidEngine implements IEvaluationContext {
|
|||
int i = 1;
|
||||
while (i < cnt.length() && !Character.isWhitespace(cnt.charAt(i)))
|
||||
i++;
|
||||
if (i == cnt.length() || i == 0)
|
||||
throw new FHIRException(engine.getWorker().formatMessage(I18nConstants.LIQUID_SYNTAX_INCLUDE, name + ": Error reading include: " + cnt));
|
||||
if (i == 0)
|
||||
throw new FHIRException(engine.getWorker().formatMessage(I18nConstants.LIQUID_SYNTAX_INCLUDE, name, cnt));
|
||||
LiquidInclude res = new LiquidInclude();
|
||||
res.page = cnt.substring(0, i);
|
||||
while (i < cnt.length() && Character.isWhitespace(cnt.charAt(i)))
|
||||
|
|
|
@ -92,7 +92,7 @@ public class ResourceLanguageFileBuilder {
|
|||
|
||||
|
||||
private boolean isTranslatable(Property p, Base b, String id) {
|
||||
if (new ContextUtilities(context).isPrimitiveDatatype(b.fhirType())) { // never any translations for non-primitives
|
||||
if (context.isPrimitiveType(b.fhirType())) { // never any translations for non-primitives
|
||||
ElementDefinition ed = null;
|
||||
for (ElementDefinition t : profile.getSnapshot().getElement()) {
|
||||
if (t.getId().equals(id)) {
|
||||
|
|
|
@ -19,7 +19,7 @@ public class CanonicalResourceManagerTests {
|
|||
private CanonicalResource resource;
|
||||
|
||||
public DeferredLoadTestResource(CanonicalResource resource) {
|
||||
super(resource.fhirType(), resource.getId(), resource.getUrl(), resource.getVersion(), resource instanceof CodeSystem ? ((CodeSystem) resource).getSupplements() : null);
|
||||
super(resource.fhirType(), resource.getId(), resource.getUrl(), resource.getVersion(), resource instanceof CodeSystem ? ((CodeSystem) resource).getSupplements() : null, null);
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import org.hl7.fhir.exceptions.FHIRException;
|
|||
import org.hl7.fhir.exceptions.PathEngineException;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
||||
import org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement;
|
||||
import org.hl7.fhir.r5.elementmodel.ValidatedFragment;
|
||||
import org.hl7.fhir.r5.formats.JsonParser;
|
||||
import org.hl7.fhir.r5.formats.XmlParser;
|
||||
import org.hl7.fhir.r5.model.*;
|
||||
|
@ -209,7 +209,7 @@ public class FHIRPathTests {
|
|||
if (node != null) {
|
||||
try {
|
||||
if ("element".equals(test.getAttribute("mode"))) {
|
||||
List<NamedElement> e = Manager.parse(fp.getWorker(), TestingUtilities.loadTestResourceStream("r5", input), input.endsWith(".json") ? FhirFormat.JSON : FhirFormat.XML);
|
||||
List<ValidatedFragment> e = Manager.parse(fp.getWorker(), TestingUtilities.loadTestResourceStream("r5", input), input.endsWith(".json") ? FhirFormat.JSON : FhirFormat.XML);
|
||||
outcome = fp.evaluate(e.get(0).getElement(), node);
|
||||
} else {
|
||||
outcome = fp.evaluate(res, node);
|
||||
|
|
|
@ -138,6 +138,15 @@ public class CommaSeparatedStringBuilder {
|
|||
return self.toString();
|
||||
}
|
||||
|
||||
|
||||
public static String buildObjects(List<? extends Object> list) {
|
||||
CommaSeparatedStringBuilder self = new CommaSeparatedStringBuilder();
|
||||
for (Object s : list) {
|
||||
self.append(s.toString());
|
||||
}
|
||||
return self.toString();
|
||||
}
|
||||
|
||||
public static Set<String> toSet(String source) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
package org.hl7.fhir.utilities;
|
||||
|
||||
public class HL7WorkGroups {
|
||||
|
||||
public static class HL7WorkGroup {
|
||||
private String link;
|
||||
private String name;
|
||||
private String code;
|
||||
|
||||
|
||||
protected HL7WorkGroup(String code, String name, String link) {
|
||||
super();
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
this.link = link;
|
||||
}
|
||||
public String getLink() {
|
||||
return link;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
public static HL7WorkGroup find(String wg) {
|
||||
String name = nameForWG(wg);
|
||||
String url = urlForWG(wg);
|
||||
if (name != null) {
|
||||
return new HL7WorkGroup(wg, name, url);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String urlForWG(String wg) {
|
||||
switch (wg) {
|
||||
case "cbcc": return "http://www.hl7.org/Special/committees/homehealth";
|
||||
case "cds": return "http://www.hl7.org/Special/committees/dss";
|
||||
case "cqi": return "http://www.hl7.org/Special/committees/cqi";
|
||||
case "cic" : return "http://www.hl7.org/Special/committees/cic";
|
||||
case "cg": return "http://www.hl7.org/Special/committees/clingenomics";
|
||||
case "dev": return "http://www.hl7.org/Special/committees/healthcaredevices";
|
||||
case "ehr": return "http://www.hl7.org/special/committees/ehr";
|
||||
case "fhir": return "http://www.hl7.org/Special/committees/fiwg";
|
||||
case "fm": return "http://www.hl7.org/Special/committees/fm";
|
||||
case "hsi": return "http://www.hl7.org/Special/committees/hsi";
|
||||
case "ii": return "http://www.hl7.org/Special/committees/imagemgt";
|
||||
case "inm": return "http://www.hl7.org/special/committees/inm";
|
||||
case "mnm": return "http://www.hl7.org/special/committees/mnm";
|
||||
case "its": return "http://www.hl7.org/special/committees/xml";
|
||||
case "oo": return "http://www.hl7.org/Special/committees/orders";
|
||||
case "pa": return "http://www.hl7.org/Special/committees/pafm";
|
||||
case "pc": return "http://www.hl7.org/Special/committees/patientcare";
|
||||
case "pe": return "http://www.hl7.org/Special/committees/patientempowerment";
|
||||
case "pher": return "http://www.hl7.org/Special/committees/pher";
|
||||
case "phx": return "http://www.hl7.org/Special/committees/medication";
|
||||
case "brr": return "http://www.hl7.org/Special/committees/rcrim";
|
||||
case "sd": return "http://www.hl7.org/Special/committees/structure";
|
||||
case "sec": return "http://www.hl7.org/Special/committees/secure";
|
||||
case "us": return "http://www.hl7.org/Special/Committees/usrealm";
|
||||
case "vocab": return "http://www.hl7.org/Special/committees/Vocab";
|
||||
case "aid": return "http://www.hl7.org/Special/committees/java";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String nameForWG(String wg) {
|
||||
switch (wg) {
|
||||
|
||||
case "cbcc": return "Community Based Collaborative Care";
|
||||
case "cds": return "Clinical Decision Support";
|
||||
case "cic" : return "Clinical Interoperability Council";
|
||||
case "cqi": return "Clinical Quality Information";
|
||||
case "cg": return "Clinical Genomics";
|
||||
case "dev": return "Health Care Devices";
|
||||
case "ehr": return "Electronic Health Records";
|
||||
case "fhir": return "FHIR Infrastructure";
|
||||
case "fm": return "Financial Management";
|
||||
case "hsi": return "Health Standards Integration";
|
||||
case "ii": return "Imaging Integration";
|
||||
case "inm": return "Infrastructure And Messaging";
|
||||
case "mnm": return "Modeling and Methodology";
|
||||
case "its": return "Implementable Technology Specifications";
|
||||
case "oo": return "Orders and Observations";
|
||||
case "pa": return "Patient Administration";
|
||||
case "pc": return "Patient Care";
|
||||
case "pe": return "Patient Empowerment";
|
||||
case "pher": return "Public Health and Emergency Response";
|
||||
case "phx": return "Pharmacy";
|
||||
case "brr": return "Biomedical Research and Regulation";
|
||||
case "sd": return "Structured Documents";
|
||||
case "sec": return "Security";
|
||||
case "us": return "US Realm Taskforce";
|
||||
case "vocab": return "Terminology Infrastructure";
|
||||
case "aid": return "Application Implementation and Design";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -9,7 +9,7 @@ public class JsonProperty {
|
|||
boolean unquotedName;
|
||||
boolean unquotedValue;
|
||||
|
||||
private int tag; // used for status in validator - faster parsing
|
||||
private int tag;
|
||||
|
||||
public JsonProperty(String name, JsonElement value) {
|
||||
super();
|
||||
|
|
|
@ -113,6 +113,7 @@ public class NpmPackage {
|
|||
private String filename;
|
||||
private String supplements;
|
||||
private String stype;
|
||||
private String derivation;
|
||||
|
||||
public PackageResourceInformation(String root, JsonObject fi) throws IOException {
|
||||
super();
|
||||
|
@ -123,6 +124,7 @@ public class NpmPackage {
|
|||
filename = Utilities.path(root, fi.asString("filename"));
|
||||
supplements = fi.asString("supplements");
|
||||
stype = fi.asString("type");
|
||||
derivation = fi.asString("derivation");
|
||||
}
|
||||
public String getId() {
|
||||
return id;
|
||||
|
@ -148,6 +150,9 @@ public class NpmPackage {
|
|||
public boolean hasId() {
|
||||
return !Utilities.noString(id);
|
||||
}
|
||||
public String getDerivation() {
|
||||
return derivation;
|
||||
}
|
||||
|
||||
}
|
||||
public class IndexVersionSorter implements Comparator<JsonObject> {
|
||||
|
@ -223,13 +228,13 @@ public class NpmPackage {
|
|||
List<String> res = new ArrayList<>();
|
||||
if (folder != null) {
|
||||
for (File f : folder.listFiles()) {
|
||||
if (!f.isDirectory() && !Utilities.existsInList(f.getName(), "package.json", ".index.json")) {
|
||||
if (!f.isDirectory() && !Utilities.existsInList(f.getName(), "package.json", ".index.json", ".index.db")) {
|
||||
res.add(f.getName());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (String s : content.keySet()) {
|
||||
if (!Utilities.existsInList(s, "package.json", ".index.json")) {
|
||||
if (!Utilities.existsInList(s, "package.json", ".index.json", ".index.db")) {
|
||||
res.add(s);
|
||||
}
|
||||
}
|
||||
|
@ -1095,12 +1100,12 @@ public class NpmPackage {
|
|||
public void save(OutputStream stream) throws IOException {
|
||||
assert !minimalMemory;
|
||||
TarArchiveOutputStream tar;
|
||||
ByteArrayOutputStream OutputStream;
|
||||
BufferedOutputStream bufferedOutputStream;
|
||||
// ByteArrayOutputStream OutputStream;
|
||||
// BufferedOutputStream bufferedOutputStream;
|
||||
GzipCompressorOutputStream gzipOutputStream;
|
||||
|
||||
OutputStream = new ByteArrayOutputStream();
|
||||
bufferedOutputStream = new BufferedOutputStream(OutputStream);
|
||||
// OutputStream = new ByteArrayOutputStream();
|
||||
// bufferedOutputStream = new BufferedOutputStream(OutputStream);
|
||||
GzipParameters gp = new GzipParameters();
|
||||
gp.setCompressionLevel(Deflater.BEST_COMPRESSION);
|
||||
gzipOutputStream = new GzipCompressorOutputStream(stream, gp);
|
||||
|
@ -1122,7 +1127,7 @@ public class NpmPackage {
|
|||
System.out.println(name+" is null");
|
||||
} else {
|
||||
indexer.seeFile(s, b);
|
||||
if (!s.equals(".index.json") && !s.equals("package.json")) {
|
||||
if (!s.equals(".index.json") && !s.equals(".index.db") && !s.equals("package.json")) {
|
||||
TarArchiveEntry entry = new TarArchiveEntry(name);
|
||||
entry.setSize(b.length);
|
||||
tar.putArchiveEntry(entry);
|
||||
|
@ -1158,10 +1163,10 @@ public class NpmPackage {
|
|||
tar.finish();
|
||||
tar.close();
|
||||
gzipOutputStream.close();
|
||||
bufferedOutputStream.close();
|
||||
OutputStream.close();
|
||||
byte[] b = OutputStream.toByteArray();
|
||||
stream.write(b);
|
||||
// bufferedOutputStream.close();
|
||||
// OutputStream.close();
|
||||
// byte[] b = OutputStream.toByteArray();
|
||||
// stream.write(b);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -45,7 +45,7 @@ public class NpmPackageIndexBuilder {
|
|||
new File(filename).delete();
|
||||
conn = DriverManager.getConnection("jdbc:sqlite:"+filename);
|
||||
Statement stmt = conn.createStatement();
|
||||
stmt.execute("CREATE TABLE index (\r\n"+
|
||||
stmt.execute("CREATE TABLE ResourceList (\r\n"+
|
||||
"FileName nvarchar NOT NULL,\r\n"+
|
||||
"ResourceType nvarchar NOT NULL,\r\n"+
|
||||
"Id nvarchar NULL,\r\n"+
|
||||
|
@ -55,10 +55,18 @@ public class NpmPackageIndexBuilder {
|
|||
"Type nvarchar NULL,\r\n"+
|
||||
"Supplements nvarchar NULL,\r\n"+
|
||||
"Content nvarchar NULL,\r\n"+
|
||||
"ValueSet nvarchar NULL,\r\n"+
|
||||
"Derivation nvarchar NULL,\r\n"+
|
||||
"PRIMARY KEY (FileName))\r\n");
|
||||
|
||||
psql = conn.prepareStatement("Insert into index (FileName, ResourceType, Id, Url, Version, Kind, Type, Supplements, Content) values (?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
psql = conn.prepareStatement("Insert into ResourceList (FileName, ResourceType, Id, Url, Version, Kind, Type, Supplements, Content, ValueSet) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
} catch (Exception e) {
|
||||
if (conn != null) {
|
||||
try {
|
||||
conn.close();
|
||||
} catch (SQLException e1) {
|
||||
}
|
||||
}
|
||||
conn = null;
|
||||
}
|
||||
}
|
||||
|
@ -95,6 +103,12 @@ public class NpmPackageIndexBuilder {
|
|||
if (json.hasPrimitive("content")) {
|
||||
fi.add("content", json.asString("content"));
|
||||
}
|
||||
if (json.hasPrimitive("valueSet")) {
|
||||
fi.add("valueSet", json.asString("valueSet"));
|
||||
}
|
||||
if (json.hasPrimitive("derivation")) {
|
||||
fi.add("derivation", json.asString("derivation"));
|
||||
}
|
||||
if (psql != null) {
|
||||
psql.setString(1, name); // FileName);
|
||||
psql.setString(2, json.asString("resourceType")); // ResourceType");
|
||||
|
@ -105,6 +119,8 @@ public class NpmPackageIndexBuilder {
|
|||
psql.setString(7, json.asString("type")); // Type");
|
||||
psql.setString(8, json.asString("supplements")); // Supplements");
|
||||
psql.setString(9, json.asString("content")); // Content");
|
||||
psql.setString(10, json.asString("valueSet")); // ValueSet");
|
||||
psql.setString(10, json.asString("derivation")); // ValueSet");
|
||||
psql.execute();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -336,15 +336,32 @@ public class XhtmlNode extends XhtmlFluent implements IBaseXhtml {
|
|||
|
||||
public String allText() {
|
||||
if (!hasChildren()) {
|
||||
if (getContent() == null) {
|
||||
return "";
|
||||
} else {
|
||||
return getContent();
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (XhtmlNode n : childNodes)
|
||||
if (n.getNodeType() == NodeType.Text)
|
||||
for (XhtmlNode n : childNodes) {
|
||||
if (n.getNodeType() == NodeType.Element && Utilities.existsInList(n.getName(), "li")) {
|
||||
b.append("* ");
|
||||
}
|
||||
if (n.getNodeType() == NodeType.Text) {
|
||||
if (n.getContent() != null) {
|
||||
b.append(n.getContent());
|
||||
else if (n.getNodeType() == NodeType.Element)
|
||||
}
|
||||
}
|
||||
if (n.getNodeType() == NodeType.Element) {
|
||||
b.append(n.allText());
|
||||
if (Utilities.existsInList(n.getName(), "p", "div", "tr", "th", "ul", "ol", "li", "h1", "h2", "h3", "h4", "h5", "h6")) {
|
||||
b.append("\r\n");
|
||||
} else if (Utilities.existsInList(n.getName(), "th", "td", "span")) {
|
||||
b.append(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
|
|
|
@ -77,9 +77,9 @@ import org.hl7.fhir.r5.elementmodel.Manager;
|
|||
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
||||
import org.hl7.fhir.r5.elementmodel.ObjectConverter;
|
||||
import org.hl7.fhir.r5.elementmodel.ParserBase;
|
||||
import org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement;
|
||||
import org.hl7.fhir.r5.elementmodel.ParserBase.ValidationPolicy;
|
||||
import org.hl7.fhir.r5.elementmodel.ResourceParser;
|
||||
import org.hl7.fhir.r5.elementmodel.ValidatedFragment;
|
||||
import org.hl7.fhir.r5.elementmodel.XmlParser;
|
||||
import org.hl7.fhir.r5.formats.FormatUtilities;
|
||||
import org.hl7.fhir.r5.model.Address;
|
||||
|
@ -173,6 +173,8 @@ import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPo
|
|||
import org.hl7.fhir.r5.utils.validation.constants.IdStatus;
|
||||
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
|
||||
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||
import org.hl7.fhir.utilities.HL7WorkGroups;
|
||||
import org.hl7.fhir.utilities.HL7WorkGroups.HL7WorkGroup;
|
||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||
import org.hl7.fhir.utilities.SIDUtilities;
|
||||
import org.hl7.fhir.utilities.StandardsStatus;
|
||||
|
@ -517,7 +519,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
private Map<String, CanonicalResourceLookupResult> crLookups = new HashMap<>();
|
||||
private boolean logProgress;
|
||||
private CodingsObserver codingObserver;
|
||||
public List<NamedElement> validatedContent;
|
||||
public List<ValidatedFragment> validatedContent;
|
||||
public boolean testMode;
|
||||
|
||||
public InstanceValidator(@Nonnull IWorkerContext theContext, @Nonnull IEvaluationContext hostServices, @Nonnull XVerExtensionManager xverManager) {
|
||||
|
@ -747,7 +749,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (validatedContent != null && !validatedContent.isEmpty()) {
|
||||
if (SAVE_INTERMEDIARIES) {
|
||||
int index = 0;
|
||||
for (NamedElement ne : validatedContent) {
|
||||
for (ValidatedFragment ne : validatedContent) {
|
||||
index++;
|
||||
saveValidatedContent(ne, index);
|
||||
}
|
||||
|
@ -761,7 +763,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
profiles.add(sd);
|
||||
}
|
||||
}
|
||||
for (NamedElement ne : validatedContent) {
|
||||
for (ValidatedFragment ne : validatedContent) {
|
||||
if (ne.getElement() != null) {
|
||||
validate(appContext, ne.getErrors(), validatedContent.size() > 1 ? ne.getName() : null, ne.getElement(), profiles);
|
||||
}
|
||||
|
@ -771,7 +773,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
return (validatedContent == null || validatedContent.isEmpty()) ? null : validatedContent.get(0).getElement(); // todo: this is broken, but fixing it really complicates things elsewhere, so we do this for now
|
||||
}
|
||||
|
||||
private void saveValidatedContent(NamedElement ne, int index) {
|
||||
private void saveValidatedContent(ValidatedFragment ne, int index) {
|
||||
String tgt = null;
|
||||
try {
|
||||
tgt = Utilities.path("[tmp]", "validator", "content");
|
||||
|
@ -4309,8 +4311,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
|
||||
public boolean isPrimitiveType(String code) {
|
||||
StructureDefinition sd = context.fetchTypeDefinition(code);
|
||||
return sd != null && sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE;
|
||||
return context.isPrimitiveType(code);
|
||||
}
|
||||
|
||||
private String getErrorMessage(String message) {
|
||||
|
@ -5404,84 +5405,20 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
}
|
||||
if (rule(errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), wg != null, I18nConstants.VALIDATION_HL7_WG_NEEDED, ToolingExtensions.EXT_WORKGROUP)) {
|
||||
String name = nameForWG(wg);
|
||||
String url = urlForWG(wg);
|
||||
if (rule(errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), name != null, I18nConstants.VALIDATION_HL7_WG_UNKNOWN, wg)) {
|
||||
String rpub = "HL7 International / "+name;
|
||||
HL7WorkGroup wgd = HL7WorkGroups.find(wg);
|
||||
if (rule(errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), wgd != null, I18nConstants.VALIDATION_HL7_WG_UNKNOWN, wg)) {
|
||||
String rpub = "HL7 International / "+wgd.getName();
|
||||
if (warning(errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), pub != null, I18nConstants.VALIDATION_HL7_PUBLISHER_MISSING, wg, rpub)) {
|
||||
warningOrError(pub.contains("/"), errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), rpub.equals(pub), I18nConstants.VALIDATION_HL7_PUBLISHER_MISMATCH, wg, rpub, pub);
|
||||
}
|
||||
warning(errors, "2023-09-15", IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(),
|
||||
Utilities.startsWithInList(url, urls), I18nConstants.VALIDATION_HL7_WG_URL, wg, url);
|
||||
Utilities.startsWithInList( wgd.getLink(), urls), I18nConstants.VALIDATION_HL7_WG_URL, wg, wgd.getLink());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String urlForWG(String wg) {
|
||||
switch (wg) {
|
||||
case "cbcc": return "http://www.hl7.org/Special/committees/homehealth";
|
||||
case "cds": return "http://www.hl7.org/Special/committees/dss";
|
||||
case "cqi": return "http://www.hl7.org/Special/committees/cqi";
|
||||
case "cg": return "http://www.hl7.org/Special/committees/clingenomics";
|
||||
case "dev": return "http://www.hl7.org/Special/committees/healthcaredevices";
|
||||
case "ehr": return "http://www.hl7.org/special/committees/ehr";
|
||||
case "fhir": return "http://www.hl7.org/Special/committees/fiwg";
|
||||
case "fm": return "http://www.hl7.org/Special/committees/fm";
|
||||
case "hsi": return "http://www.hl7.org/Special/committees/hsi";
|
||||
case "ii": return "http://www.hl7.org/Special/committees/imagemgt";
|
||||
case "inm": return "http://www.hl7.org/special/committees/inm";
|
||||
case "mnm": return "http://www.hl7.org/special/committees/mnm";
|
||||
case "its": return "http://www.hl7.org/special/committees/xml";
|
||||
case "oo": return "http://www.hl7.org/Special/committees/orders";
|
||||
case "pa": return "http://www.hl7.org/Special/committees/pafm";
|
||||
case "pc": return "http://www.hl7.org/Special/committees/patientcare";
|
||||
case "pe": return "http://www.hl7.org/Special/committees/patientempowerment";
|
||||
case "pher": return "http://www.hl7.org/Special/committees/pher";
|
||||
case "phx": return "http://www.hl7.org/Special/committees/medication";
|
||||
case "brr": return "http://www.hl7.org/Special/committees/rcrim";
|
||||
case "sd": return "http://www.hl7.org/Special/committees/structure";
|
||||
case "sec": return "http://www.hl7.org/Special/committees/secure";
|
||||
case "us": return "http://www.hl7.org/Special/Committees/usrealm";
|
||||
case "vocab": return "http://www.hl7.org/Special/committees/Vocab";
|
||||
case "aid": return "http://www.hl7.org/Special/committees/java";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String nameForWG(String wg) {
|
||||
switch (wg) {
|
||||
|
||||
case "cbcc": return "Community Based Collaborative Care";
|
||||
case "cds": return "Clinical Decision Support";
|
||||
case "cqi": return "Clinical Quality Information";
|
||||
case "cg": return "Clinical Genomics";
|
||||
case "dev": return "Health Care Devices";
|
||||
case "ehr": return "Electronic Health Records";
|
||||
case "fhir": return "FHIR Infrastructure";
|
||||
case "fm": return "Financial Management";
|
||||
case "hsi": return "Health Standards Integration";
|
||||
case "ii": return "Imaging Integration";
|
||||
case "inm": return "Infrastructure And Messaging";
|
||||
case "mnm": return "Modeling and Methodology";
|
||||
case "its": return "Implementable Technology Specifications";
|
||||
case "oo": return "Orders and Observations";
|
||||
case "pa": return "Patient Administration";
|
||||
case "pc": return "Patient Care";
|
||||
case "pe": return "Patient Empowerment";
|
||||
case "pher": return "Public Health and Emergency Response";
|
||||
case "phx": return "Pharmacy";
|
||||
case "brr": return "Biomedical Research and Regulation";
|
||||
case "sd": return "Structured Documents";
|
||||
case "sec": return "Security";
|
||||
case "us": return "US Realm Taskforce";
|
||||
case "vocab": return "Terminology Infrastructure";
|
||||
case "aid": return "Application Implementation and Design";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean statusCodesConsistent(String status, String standardsStatus) {
|
||||
switch (standardsStatus) {
|
||||
case "draft": return Utilities.existsInList(status, "draft");
|
||||
|
|
|
@ -481,7 +481,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
if (v != null) {
|
||||
ok = rule(errors, NO_RULE_DATE, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), typeCodes.contains(v.fhirType()), I18nConstants.SD_VALUE_TYPE_IILEGAL, element.getIdBase(), "fixed", v.fhirType(), typeCodes) && ok;
|
||||
hint(errors, NO_RULE_DATE, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), !repeating, I18nConstants.SD_VALUE_TYPE_REPEAT_HINT, element.getIdBase(), "fixed");
|
||||
if (isPrimitiveType(v.fhirType())) {
|
||||
if (context.isPrimitiveType(v.fhirType())) {
|
||||
warning(errors, NO_RULE_DATE, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), !repeating, I18nConstants.SD_VALUE_TYPE_REPEAT_WARNING_DOTNET, element.getIdBase(), "fixed");
|
||||
} else {
|
||||
warning(errors, NO_RULE_DATE, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), false, I18nConstants.SD_VALUE_COMPLEX_FIXED, v.fhirType());
|
||||
|
@ -491,7 +491,7 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
if (v != null) {
|
||||
ok = rule(errors, NO_RULE_DATE, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), typeCodes.contains(v.fhirType()), I18nConstants.SD_VALUE_TYPE_IILEGAL, element.getIdBase(), "pattern", v.fhirType(), typeCodes) && ok;
|
||||
hint(errors, NO_RULE_DATE, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), !repeating, I18nConstants.SD_VALUE_TYPE_REPEAT_HINT, element.getIdBase(), "pattern");
|
||||
if (isPrimitiveType(v.fhirType())) {
|
||||
if (context.isPrimitiveType(v.fhirType())) {
|
||||
warning(errors, NO_RULE_DATE, IssueType.EXCEPTION, stack.push(v, -1, null, null).getLiteralPath(), !repeating, I18nConstants.SD_VALUE_TYPE_REPEAT_WARNING_DOTNET, element.getIdBase(), "pattern");
|
||||
}
|
||||
}
|
||||
|
@ -737,10 +737,6 @@ public class StructureDefinitionValidator extends BaseValidator {
|
|||
return true;
|
||||
}
|
||||
|
||||
private boolean isPrimitiveType(String fhirType) {
|
||||
StructureDefinition sd = context.fetchTypeDefinition(fhirType);
|
||||
return sd != null && sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE;
|
||||
}
|
||||
|
||||
private String boundType(Set<String> typeCodes) {
|
||||
for (String tc : typeCodes) {
|
||||
|
|
|
@ -22,6 +22,9 @@ public class FHIRPathExpressionFixer {
|
|||
if ("txt-2".equals(key)) {
|
||||
return "htmlChecks2()";
|
||||
}
|
||||
if ("dom-6".equals(key)) {
|
||||
return "(%rootResource != $this) or text.`div`.exists()";
|
||||
}
|
||||
if ("generated='generated' implies source.empty()".equals(expr)) {
|
||||
return "generation='generated' implies source.empty()";
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ public class NodeStack {
|
|||
if (en.endsWith("[x]")) {
|
||||
en = en.substring(0, en.length() - 3);
|
||||
String t = n.substring(en.length());
|
||||
if (isPrimitiveType(Utilities.uncapitalize(t)))
|
||||
if (context.isPrimitiveType(Utilities.uncapitalize(t)))
|
||||
t = Utilities.uncapitalize(t);
|
||||
res.literalPath = res.literalPath.substring(0, res.literalPath.lastIndexOf(".")) + "." + en + ".ofType(" + t + ")";
|
||||
} else {
|
||||
|
@ -194,10 +194,6 @@ public class NodeStack {
|
|||
return path.substring(path.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
public boolean isPrimitiveType(String code) {
|
||||
StructureDefinition sd = context.fetchTypeDefinition(code);
|
||||
return sd != null && sd.getKind() == StructureDefinitionKind.PRIMITIVETYPE;
|
||||
}
|
||||
|
||||
public String getWorkingLang() {
|
||||
return workingLang;
|
||||
|
|
Loading…
Reference in New Issue