autofix slice names + check differentials
This commit is contained in:
parent
ee6e0d90de
commit
06d6d9452a
|
@ -265,6 +265,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
private ValidationOptions terminologyServiceOptions = new ValidationOptions();
|
||||
private boolean newSlicingProcessing;
|
||||
private String defWebRoot;
|
||||
private boolean autoFixSliceNames;
|
||||
|
||||
public ProfileUtilities(IWorkerContext context, List<ValidationMessage> messages, ProfileKnowledgeProvider pkp) {
|
||||
super();
|
||||
|
@ -281,11 +282,21 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
return igmode;
|
||||
}
|
||||
|
||||
|
||||
public void setIgmode(boolean igmode) {
|
||||
this.igmode = igmode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isAutoFixSliceNames() {
|
||||
return autoFixSliceNames;
|
||||
}
|
||||
|
||||
public ProfileUtilities setAutoFixSliceNames(boolean autoFixSliceNames) {
|
||||
this.autoFixSliceNames = autoFixSliceNames;
|
||||
return this;
|
||||
}
|
||||
|
||||
public interface ProfileKnowledgeProvider {
|
||||
public class BindingResolution {
|
||||
public String display;
|
||||
|
@ -479,6 +490,8 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
derived.setSnapshot(new StructureDefinitionSnapshotComponent());
|
||||
|
||||
try {
|
||||
checkDifferential(derived.getDifferential().getElement(), derived.getType(), derived.getUrl());
|
||||
|
||||
// so we have two lists - the base list, and the differential list
|
||||
// the differential list is only allowed to include things that are in the base list, but
|
||||
// is allowed to include them multiple times - thereby slicing them
|
||||
|
@ -611,6 +624,54 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
}
|
||||
}
|
||||
|
||||
private void checkDifferential(List<ElementDefinition> elements, String type, String url) {
|
||||
boolean first = true;
|
||||
for (ElementDefinition ed : elements) {
|
||||
if (!ed.hasPath()) {
|
||||
throw new FHIRException("No path on element in differential in "+url);
|
||||
}
|
||||
String p = ed.getPath();
|
||||
if (p == null) {
|
||||
throw new FHIRException("No path value on element in differential in "+url);
|
||||
}
|
||||
if (!((first && type.equals(p)) || p.startsWith(type+"."))) {
|
||||
throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": must start with "+type+"."+(first ? " (o be '"+type+"')" : ""));
|
||||
}
|
||||
if (p.contains(".")) {
|
||||
// Element names (the parts of a path delineated by the '.' character) SHALL NOT contain whitespace (i.e. Unicode characters marked as whitespace)
|
||||
// Element names SHALL NOT contain the characters ,:;'"/|?!@#$%^&*()[]{}
|
||||
// Element names SHOULD not contain non-ASCII characters
|
||||
// Element names SHALL NOT exceed 64 characters in length
|
||||
String[] pl = p.split("\\.");
|
||||
for (String pp : pl) {
|
||||
if (pp.length() < 1) {
|
||||
throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": name portion mising ('..')");
|
||||
}
|
||||
if (pp.length() > 64) {
|
||||
throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": name portion exceeds 64 chars in length");
|
||||
}
|
||||
for (char ch : pp.toCharArray()) {
|
||||
if (Character.isWhitespace(ch)) {
|
||||
throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": no unicode whitespace");
|
||||
}
|
||||
if (Utilities.existsInList(ch, ',', ':', ';', '\'', '"', '/', '|', '?', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '{', '}')) {
|
||||
throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": illegal character '"+ch+"'");
|
||||
}
|
||||
if (ch < ' ' || ch > 'z') {
|
||||
throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": illegal character '"+ch+"'");
|
||||
}
|
||||
}
|
||||
if (pp.contains("[") || pp.contains("]")) {
|
||||
if (!pp.endsWith("[x]") || (pp.substring(0, pp.length()-3).contains("[") || (pp.substring(0, pp.length()-3).contains("]")))) {
|
||||
throw new FHIRException("Illegal path '"+p+"' in differential in "+url+": illegal characters []");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean isCompatibleType(String base, String type) {
|
||||
StructureDefinition sd = context.fetchTypeDefinition(type);
|
||||
while (sd != null) {
|
||||
|
@ -958,7 +1019,11 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (!ts.defn.hasSliceName()) {
|
||||
ts.defn.setSliceName(tn);
|
||||
} else if (!ts.defn.getSliceName().equals(tn)) {
|
||||
throw new FHIRException("Error at path "+(!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath)+": Slice name must be '"+tn+"' but is '"+ts.defn.getSliceName()+"'");
|
||||
if (autoFixSliceNames) {
|
||||
ts.defn.setSliceName(tn);
|
||||
} else {
|
||||
throw new FHIRException("Error at path "+(!Utilities.noString(contextPathSrc) ? contextPathSrc : cpath)+": Slice name must be '"+tn+"' but is '"+ts.defn.getSliceName()+"'");
|
||||
}
|
||||
} if (!ts.defn.hasType()) {
|
||||
ts.defn.addType().setCode(ts.type);
|
||||
} else if (ts.defn.getType().size() > 1) {
|
||||
|
@ -2424,7 +2489,7 @@ public class ProfileUtilities extends TranslatingUtilities {
|
|||
if (messages == null) {
|
||||
throw new FHIRException("Error at "+purl+"#"+derived.getPath()+": The target profile "+url+" is not valid constraint on the base ("+td.getTargetProfile()+")");
|
||||
} else {
|
||||
messages.add(new ValidationMessage(Source.InstanceValidator, IssueType.BUSINESSRULE, derived.getPath(), "The target profile "+u.getValue()+" is not a valid constraint on the base ("+td.getTargetProfile()+")", IssueSeverity.ERROR));
|
||||
messages.add(new ValidationMessage(Source.InstanceValidator, IssueType.BUSINESSRULE, derived.getPath(), "The target profile "+u.getValue()+" is not a valid constraint on the base ("+td.getTargetProfile()+") at "+derived.getPath(), IssueSeverity.ERROR));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue