various fixes for reported bugs (#252)

* fix bug in Definition mode - support ofType()

* fix bug reading old packages

* fix for invalid OperationOutome if nothing is wrong

* more fix for when no errors found
This commit is contained in:
Grahame Grieve 2020-06-20 06:02:56 +10:00 committed by GitHub
parent c1f5244873
commit 0e8b5f6552
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 81 additions and 41 deletions

View File

@ -4433,7 +4433,8 @@ public class FHIRPathEngine {
public ElementDefinition evaluateDefinition(ExpressionNode expr, StructureDefinition profile, ElementDefinition element) throws DefinitionException {
StructureDefinition sd = profile;
ElementDefinition focus = null;
boolean okToNotResolve = false;
if (expr.getKind() == Kind.Name) {
if (element.hasSlicing()) {
ElementDefinition slice = pickMandatorySlice(sd, element);
@ -4493,6 +4494,19 @@ public class FHIRPathEngine {
}
}
}
} else if ("ofType".equals(expr.getName())) {
if (!element.hasType())
throw new DefinitionException("illegal use of ofType() in discriminator - no type on element "+element.getId());
if (element.getType().size() > 1)
throw new DefinitionException("illegal use of ofType() in discriminator - Multiple possible types on "+element.getId());
if (!element.getType().get(0).hasCode())
throw new DefinitionException("illegal use of ofType() in discriminator - Type has no code on "+element.getId());
String atn = element.getType().get(0).getCode();
String stn = expr.getParameters().get(0).getName();
okToNotResolve = true;
if ((atn.equals(stn))) {
focus = element;
}
} else
throw new DefinitionException("illegal function name "+expr.getName()+"() in discriminator");
} else if (expr.getKind() == Kind.Group) {
@ -4501,9 +4515,13 @@ public class FHIRPathEngine {
throw new DefinitionException("illegal expression syntax in discriminator (const)");
}
if (focus == null)
throw new DefinitionException("Unable to resolve discriminator in definitions: "+expr.toString());
else if (expr.getInner() == null)
if (focus == null) {
if (okToNotResolve) {
return null;
} else {
throw new DefinitionException("Unable to resolve discriminator in definitions: "+expr.toString());
}
} else if (expr.getInner() == null)
return focus;
else {
return evaluateDefinition(expr.getInner(), sd, focus);

View File

@ -120,7 +120,10 @@ public class NpmPackage {
return name;
}
public void readIndex(JsonObject index) {
public boolean readIndex(JsonObject index) {
if (!index.has("index-version") || (index.get("index-version").getAsInt() != 1)) {
return false;
}
this.index = index;
for (JsonElement e : index.getAsJsonArray("files")) {
JsonObject file = (JsonObject) e;
@ -130,6 +133,7 @@ public class NpmPackage {
types.put(type, new ArrayList<>());
types.get(type).add(name);
}
return true;
}
public List<String> listFiles() {
@ -210,7 +214,7 @@ public class NpmPackage {
*/
public static NpmPackage fromFolder(String path) throws IOException {
NpmPackage res = new NpmPackage();
loadFiles(res, path, new File(path));
res.loadFiles(path, new File(path));
res.checkIndexed(path);
return res;
}
@ -228,9 +232,9 @@ public class NpmPackage {
return userData;
}
public static void loadFiles(NpmPackage res, String path, File source, String... exemptions) throws FileNotFoundException, IOException {
res.npm = (JsonObject) new com.google.gson.JsonParser().parse(TextFile.fileToString(Utilities.path(path, "package", "package.json")));
res.path = path;
public void loadFiles(String path, File source, String... exemptions) throws FileNotFoundException, IOException {
this.npm = (JsonObject) new com.google.gson.JsonParser().parse(TextFile.fileToString(Utilities.path(path, "package", "package.json")));
this.path = path;
File dir = new File(path);
for (File f : dir.listFiles()) {
@ -240,22 +244,24 @@ public class NpmPackage {
if (!d.equals("package")) {
d = Utilities.path("package", d);
}
NpmPackageFolder folder = res.new NpmPackageFolder(d);
NpmPackageFolder folder = this.new NpmPackageFolder(d);
folder.folder = f;
res.folders.put(d, folder);
this.folders.put(d, folder);
File ij = new File(Utilities.path(f.getAbsolutePath(), ".index.json"));
if (ij.exists()) {
try {
folder.readIndex(JsonTrackingParser.parseJson(ij));
if (!folder.readIndex(JsonTrackingParser.parseJson(ij))) {
indexFolder(folder.getName(), folder);
}
} catch (Exception e) {
throw new IOException("Error parsing "+ij.getAbsolutePath()+": "+e.getMessage(), e);
}
}
loadSubFolders(res, dir.getAbsolutePath(), f);
loadSubFolders(dir.getAbsolutePath(), f);
} else {
NpmPackageFolder folder = res.new NpmPackageFolder(Utilities.path("package", "$root"));
NpmPackageFolder folder = this.new NpmPackageFolder(Utilities.path("package", "$root"));
folder.folder = dir;
res.folders.put(Utilities.path("package", "$root"), folder);
this.folders.put(Utilities.path("package", "$root"), folder);
}
}
}
@ -265,25 +271,27 @@ public class NpmPackage {
return Utilities.existsInList(f.getName(), ".git", ".svn") || Utilities.existsInList(f.getName(), "package-list.json");
}
private static void loadSubFolders(NpmPackage res, String rootPath, File dir) throws IOException {
private void loadSubFolders(String rootPath, File dir) throws IOException {
for (File f : dir.listFiles()) {
if (f.isDirectory()) {
String d = f.getAbsolutePath().substring(rootPath.length()+1);
if (!d.startsWith("package")) {
d = Utilities.path("package", d);
}
NpmPackageFolder folder = res.new NpmPackageFolder(d);
NpmPackageFolder folder = this.new NpmPackageFolder(d);
folder.folder = f;
res.folders.put(d, folder);
this.folders.put(d, folder);
File ij = new File(Utilities.path(f.getAbsolutePath(), ".index.json"));
if (ij.exists()) {
try {
folder.readIndex(JsonTrackingParser.parseJson(ij));
if (!folder.readIndex(JsonTrackingParser.parseJson(ij))) {
indexFolder(folder.getName(), folder);
}
} catch (Exception e) {
throw new IOException("Error parsing "+ij.getAbsolutePath()+": "+e.getMessage(), e);
}
}
loadSubFolders(res, rootPath, f);
loadSubFolders(rootPath, f);
}
}
@ -291,7 +299,7 @@ public class NpmPackage {
public static NpmPackage fromFolder(String folder, PackageType defType, String... exemptions) throws IOException {
NpmPackage res = new NpmPackage();
loadFiles(res, folder, new File(folder), exemptions);
res.loadFiles(folder, new File(folder), exemptions);
if (!res.folders.containsKey("package")) {
res.folders.put("package", res.new NpmPackageFolder("package"));
}
@ -386,29 +394,36 @@ public class NpmPackage {
private void checkIndexed(String desc) throws IOException {
for (NpmPackageFolder folder : folders.values()) {
List<String> remove = new ArrayList<>();
if (folder.index == null) {
NpmPackageIndexBuilder indexer = new NpmPackageIndexBuilder();
indexer.start();
for (String n : folder.listFiles()) {
if (!indexer.seeFile(n, folder.fetchFile(n))) {
remove.add(n);
}
}
for (String n : remove) {
folder.removeFile(n);
}
String json = indexer.build();
try {
folder.readIndex(JsonTrackingParser.parseJson(json));
} catch (Exception e) {
TextFile.stringToFile(json, Utilities.path("[tmp]", ".index.json"));
throw new IOException("Error parsing "+(desc == null ? "" : desc+"#")+"package/"+folder.name+"/.index.json: "+e.getMessage(), e);
}
indexFolder(desc, folder);
}
}
}
public void indexFolder(String desc, NpmPackageFolder folder) throws FileNotFoundException, IOException {
List<String> remove = new ArrayList<>();
NpmPackageIndexBuilder indexer = new NpmPackageIndexBuilder();
indexer.start();
for (String n : folder.listFiles()) {
if (!indexer.seeFile(n, folder.fetchFile(n))) {
remove.add(n);
}
}
for (String n : remove) {
folder.removeFile(n);
}
String json = indexer.build();
try {
folder.readIndex(JsonTrackingParser.parseJson(json));
if (folder.folder != null) {
TextFile.stringToFile(json, Utilities.path(folder.folder.getAbsolutePath(), ".index.json"));
}
} catch (Exception e) {
TextFile.stringToFile(json, Utilities.path("[tmp]", ".index.json"));
throw new IOException("Error parsing "+(desc == null ? "" : desc+"#")+"package/"+folder.name+"/.index.json: "+e.getMessage(), e);
}
}
public static NpmPackage fromZip(InputStream stream, boolean dropRootFolder, String desc) throws IOException {
NpmPackage res = new NpmPackage();

View File

@ -501,4 +501,5 @@ public class I18nConstants {
public static final String _HAS_CHILDREN__AND_MULTIPLE_TYPES__IN_PROFILE_ = "_has_children__and_multiple_types__in_profile_";
public static final String _HAS_CHILDREN__FOR_TYPE__IN_PROFILE__BUT_CANT_FIND_TYPE = "_has_children__for_type__in_profile__but_cant_find_type";
public static final String _HAS_NO_CHILDREN__AND_NO_TYPES_IN_PROFILE_ = "_has_no_children__and_no_types_in_profile_";
public static final String ALL_OK = "ALL_OK";
}

View File

@ -502,3 +502,4 @@ VALIDATION_VAL_ILLEGAL_TYPE_CONSTRAINT = Illegal constraint in profile {0} at pa
EXTENSION_EXT_CONTEXT_WRONG_XVER = The extension {0} from FHIR version {3} is not allowed to be used at this point (allowed = {1}; this element is [{2}; this is a warning since contexts may be renamed between FHIR versions)
SECURITY_STRING_CONTENT_ERROR = The string value contains embedded HTML tags, which are not allowed for security reasons in this context
SECURITY_STRING_CONTENT_WARNING = The string value contains embedded HTML tags. Note that all inputs should be escaped when rendered to HTML as a matter of course
ALL_OK = All OK

View File

@ -40,6 +40,8 @@ import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.cache.NpmPackage;
import org.hl7.fhir.utilities.cache.FilesystemPackageCacheManager;
import org.hl7.fhir.utilities.cache.ToolsVersion;
import org.hl7.fhir.utilities.i18n.I18nBase;
import org.hl7.fhir.utilities.i18n.I18nConstants;
import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
@ -1191,6 +1193,9 @@ public class ValidationEngine implements IValidatorResourceFetcher {
}
op.getIssue().add(OperationOutcomeUtilities.convertToIssue(vm, op));
}
if (!op.hasIssue()) {
op.addIssue().setSeverity(OperationOutcome.IssueSeverity.INFORMATION).setCode(OperationOutcome.IssueType.INFORMATIONAL).getDetails().setText(context.formatMessage(I18nConstants.ALL_OK));
}
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
RendererFactory.factory(op, rc).render(op);
return op;

View File

@ -38,7 +38,7 @@ public class ValidationEngineTests {
}
Assertions.assertEquals(0, e);
Assertions.assertEquals(0, w);
Assertions.assertEquals(0, h);
Assertions.assertEquals(1, h);
}
@Test
@ -52,7 +52,7 @@ public class ValidationEngineTests {
int h = hints(op);
Assertions.assertEquals(0, e);
Assertions.assertEquals(0, w);
Assertions.assertEquals(0, h);
Assertions.assertEquals(1, h);
if (!TestUtilities.silent)
System.out.println(" .. done: " + Integer.toString(e) + " errors, " + Integer.toString(w) + " warnings, " + Integer.toString(h) + " information messages");
}