use of org.hl7.fhir.r4b.model.Property in project org.hl7.fhir.core by hapifhir.
the class ProfileDrivenRenderer method splitExtensions.
private List<PropertyWrapper> splitExtensions(StructureDefinition profile, List<PropertyWrapper> children) throws UnsupportedEncodingException, IOException, FHIRException {
List<PropertyWrapper> results = new ArrayList<PropertyWrapper>();
Map<String, PropertyWrapper> map = new HashMap<String, PropertyWrapper>();
for (PropertyWrapper p : children) if (p.getName().equals("extension") || p.getName().equals("modifierExtension")) {
// we're going to split these up, and create a property for each url
if (p.hasValues()) {
for (BaseWrapper v : p.getValues()) {
Extension ex = (Extension) v.getBase();
String url = ex.getUrl();
StructureDefinition ed = getContext().getWorker().fetchResource(StructureDefinition.class, url);
if (ed == null) {
if (xverManager == null) {
xverManager = new XVerExtensionManager(context.getWorker());
}
if (xverManager.matchingUrl(url) && xverManager.status(url) == XVerExtensionStatus.Valid) {
ed = xverManager.makeDefinition(url);
getContext().getWorker().generateSnapshot(ed);
getContext().getWorker().cacheResource(ed);
}
}
if (p.getName().equals("modifierExtension") && ed == null) {
throw new DefinitionException("Unknown modifier extension " + url);
}
PropertyWrapper pe = map.get(p.getName() + "[" + url + "]");
if (pe == null) {
if (ed == null) {
if (url.startsWith("http://hl7.org/fhir") && !url.startsWith("http://hl7.org/fhir/us")) {
throw new DefinitionException("unknown extension " + url);
}
// System.out.println("unknown extension "+url);
pe = new PropertyWrapperDirect(this.context, new Property(p.getName() + "[" + url + "]", p.getTypeCode(), p.getDefinition(), p.getMinCardinality(), p.getMaxCardinality(), ex), null);
} else {
ElementDefinition def = ed.getSnapshot().getElement().get(0);
pe = new PropertyWrapperDirect(this.context, new Property(p.getName() + "[" + url + "]", "Extension", def.getDefinition(), def.getMin(), def.getMax().equals("*") ? Integer.MAX_VALUE : Integer.parseInt(def.getMax()), ex), ed.getSnapshot().getElementFirstRep());
((PropertyWrapperDirect) pe).getWrapped().setStructure(ed);
}
results.add(pe);
} else
pe.getValues().add(v);
}
}
} else
results.add(p);
return results;
}
use of org.hl7.fhir.r4b.model.Property in project org.hl7.fhir.core by hapifhir.
the class CanonicalSpreadsheetGenerator method renderCanonicalResource.
protected Sheet renderCanonicalResource(CanonicalResource cr) {
Sheet sheet = makeSheet("Metadata");
Row headerRow = sheet.createRow(0);
addCell(headerRow, 0, "Property", styles.get("header"));
addCell(headerRow, 1, "Value", styles.get("header"));
addMetadataRow(sheet, "URL", cr.getUrl());
for (Identifier id : cr.getIdentifier()) {
addMetadataRow(sheet, "Identifier", dr.display(id));
}
addMetadataRow(sheet, "Version", cr.getVersion());
addMetadataRow(sheet, "Name", cr.getName());
addMetadataRow(sheet, "Title", cr.getTitle());
addMetadataRow(sheet, "Status", cr.getStatusElement().asStringValue());
addMetadataRow(sheet, "Experimental", cr.getExperimentalElement().asStringValue());
addMetadataRow(sheet, "Date", cr.getDateElement().asStringValue());
addMetadataRow(sheet, "Publisher", cr.getPublisher());
for (ContactDetail c : cr.getContact()) {
addMetadataRow(sheet, "Contact", dr.display(c));
}
for (CodeableConcept j : cr.getJurisdiction()) {
addMetadataRow(sheet, "Jurisdiction", dr.display(j));
}
addMetadataRow(sheet, "Description", cr.getDescription());
addMetadataRow(sheet, "Purpose", cr.getPurpose());
addMetadataRow(sheet, "Copyright", cr.getCopyright());
configureSheet(sheet);
return sheet;
}
use of org.hl7.fhir.r4b.model.Property in project org.hl7.fhir.core by hapifhir.
the class ProfileComparer method compareElements.
private void compareElements(ProfileComparison comp, StructuralMatch<ElementDefinitionNode> res, String path, String sliceName, DefinitionNavigator left, DefinitionNavigator right) throws DefinitionException, FHIRFormatError, IOException {
assert (path != null);
assert (left != null);
assert (right != null);
assert (left.path().equals(right.path()));
if (session.isDebug()) {
System.out.println("Compare elements at " + path);
}
// not allowed to be different:
// ruleEqual(comp, res, left.current().getDefaultValue(), right.current().getDefaultValue(), "defaultValue", path);
// ruleEqual(comp, res, left.current().getMeaningWhenMissingElement(), right.current().getMeaningWhenMissingElement(), "meaningWhenMissing", path);
// ruleEqual(comp, res, left.current().getIsModifierElement(), right.current().getIsModifierElement(), "isModifier", path); - this check belongs in the core
// ruleEqual(comp, res, left.current().getIsSummaryElement(), right.current().getIsSummaryElement(), "isSummary", path); - so does this
// we ignore slicing right now - we're going to clone the root one anyway, and then think about clones
// simple stuff
ElementDefinition subset = new ElementDefinition();
subset.setPath(left.path());
if (sliceName != null)
subset.setSliceName(sliceName);
// can't be bothered even testing this one
subset.getRepresentation().addAll(left.current().getRepresentation());
subset.setDefaultValue(left.current().getDefaultValue());
subset.setMeaningWhenMissing(left.current().getMeaningWhenMissing());
subset.setIsModifier(left.current().getIsModifier());
subset.setIsSummary(left.current().getIsSummary());
// descriptive properties from ElementDefinition - merge them:
subset.setLabel(mergeText(comp, res, path, "label", left.current().getLabel(), right.current().getLabel(), false));
subset.setShort(mergeText(comp, res, path, "short", left.current().getShort(), right.current().getShort(), false));
subset.setDefinition(mergeText(comp, res, path, "definition", left.current().getDefinition(), right.current().getDefinition(), false));
subset.setComment(mergeText(comp, res, path, "comments", left.current().getComment(), right.current().getComment(), false));
subset.setRequirements(mergeText(comp, res, path, "requirements", left.current().getRequirements(), right.current().getRequirements(), false));
subset.getCode().addAll(mergeCodings(left.current().getCode(), right.current().getCode()));
subset.getAlias().addAll(mergeStrings(left.current().getAlias(), right.current().getAlias()));
subset.getMapping().addAll(mergeMappings(left.current().getMapping(), right.current().getMapping()));
// left will win for example
subset.setExample(left.current().hasExample() ? left.current().getExample() : right.current().getExample());
if (left.current().getMustSupport() != right.current().getMustSupport()) {
vm(IssueSeverity.WARNING, "Elements differ in definition for mustSupport: '" + left.current().getMustSupport() + "' vs '" + right.current().getMustSupport() + "'", path, comp.getMessages(), res.getMessages());
}
subset.setMustSupport(left.current().getMustSupport() || right.current().getMustSupport());
ElementDefinition superset = subset.copy();
// compare and intersect
int leftMin = left.current().getMin();
int rightMin = right.current().getMin();
int leftMax = "*".equals(left.current().getMax()) ? Integer.MAX_VALUE : Integer.parseInt(left.current().getMax());
int rightMax = "*".equals(right.current().getMax()) ? Integer.MAX_VALUE : Integer.parseInt(right.current().getMax());
checkMinMax(comp, res, path, leftMin, rightMin, leftMax, rightMax);
superset.setMin(unionMin(leftMin, rightMin));
superset.setMax(unionMax(leftMax, rightMax, left.current().getMax(), right.current().getMax()));
subset.setMin(intersectMin(leftMin, rightMin));
subset.setMax(intersectMax(leftMax, rightMax, left.current().getMax(), right.current().getMax()));
superset.getType().addAll(unionTypes(comp, res, path, left.current().getType(), right.current().getType()));
subset.getType().addAll(intersectTypes(comp, res, subset, path, left.current().getType(), right.current().getType()));
rule(comp, res, !subset.getType().isEmpty() || (!left.current().hasType() && !right.current().hasType()), path, "Type Mismatch: " + typeCode(left) + " vs " + typeCode(right));
// <fixed[x]><!-- ?? 0..1 * Value must be exactly this --></fixed[x]>
// <pattern[x]><!-- ?? 0..1 * Value must have at least these property values --></pattern[x]>
superset.setMaxLengthElement(unionMaxLength(left.current().getMaxLength(), right.current().getMaxLength()));
subset.setMaxLengthElement(intersectMaxLength(left.current().getMaxLength(), right.current().getMaxLength()));
if (left.current().hasBinding() || right.current().hasBinding()) {
compareBindings(comp, res, subset, superset, path, left.current(), right.current());
}
// note these are backwards
superset.getConstraint().addAll(intersectConstraints(path, left.current().getConstraint(), right.current().getConstraint()));
subset.getConstraint().addAll(unionConstraints(comp, res, path, left.current().getConstraint(), right.current().getConstraint()));
comp.getIntersection().getSnapshot().getElement().add(subset);
comp.getUnion().getSnapshot().getElement().add(superset);
// add the children
compareChildren(comp, res, path, left, right);
//
// // now process the slices
// if (left.current().hasSlicing() || right.current().hasSlicing()) {
// assert sliceName == null;
// if (isExtension(left.path()))
// return compareExtensions(outcome, path, superset, subset, left, right);
// // return true;
// else {
// ElementDefinitionSlicingComponent slicingL = left.current().getSlicing();
// ElementDefinitionSlicingComponent slicingR = right.current().getSlicing();
// // well, this is tricky. If one is sliced, and the other is not, then in general, the union just ignores the slices, and the intersection is the slices.
// if (left.current().hasSlicing() && !right.current().hasSlicing()) {
// // the super set is done. Any restrictions in the slices are irrelevant to what the super set says, except that we're going sum up the value sets if we can (for documentation purposes) (todo)
// // the minimum set is the slicing specified in the slicer
// subset.setSlicing(slicingL);
// // stick everything from the right to do with the slices to the subset
// copySlices(outcome.subset.getSnapshot().getElement(), left.getStructure().getSnapshot().getElement(), left.slices());
// } else if (!left.current().hasSlicing() && right.current().hasSlicing()) {
// // the super set is done. Any restrictions in the slices are irrelevant to what the super set says, except that we're going sum up the value sets if we can (for documentation purposes) (todo)
// // the minimum set is the slicing specified in the slicer
// subset.setSlicing(slicingR);
// // stick everything from the right to do with the slices to the subset
// copySlices(outcome.subset.getSnapshot().getElement(), right.getStructure().getSnapshot().getElement(), right.slices());
// } else if (isTypeSlicing(slicingL) || isTypeSlicing(slicingR)) {
// superset.getSlicing().setRules(SlicingRules.OPEN).setOrdered(false).addDiscriminator().setType(DiscriminatorType.TYPE).setPath("$this");
// subset.getSlicing().setRules(slicingL.getRules() == SlicingRules.CLOSED || slicingR.getRules() == SlicingRules.CLOSED ? SlicingRules.OPEN : SlicingRules.CLOSED).setOrdered(false).addDiscriminator().setType(DiscriminatorType.TYPE).setPath("$this");
//
// // the superset is the union of the types
// // the subset is the intersection of them
// List<DefinitionNavigator> handled = new ArrayList<>();
// for (DefinitionNavigator t : left.slices()) {
// DefinitionNavigator r = findMatchingSlice(right.slices(), t);
// if (r == null) {
// copySlice(outcome.superset.getSnapshot().getElement(), left.getStructure().getSnapshot().getElement(), t);
// } else {
// handled.add(r);
// ret = compareElements(outcome, path+":"+t.current().getSliceName(), t, r, t.current().getSliceName()) && ret;
// }
// }
// for (DefinitionNavigator t : right.slices()) {
// if (!handled.contains(t)) {
// copySlice(outcome.superset.getSnapshot().getElement(), right.getStructure().getSnapshot().getElement(), t);
// }
// }
// } else if (slicingMatches(slicingL, slicingR)) {
// // if it's the same, we can try matching the slices - though we might have to give up without getting matches correct
// // there amy be implied consistency we can't reason about
// throw new DefinitionException("Slicing matches but is not handled yet at "+left.current().getId()+": ("+ProfileUtilities.summarizeSlicing(slicingL)+")");
// } else {
// // if the slicing is different, we can't compare them - or can we?
// throw new DefinitionException("Slicing doesn't match at "+left.current().getId()+": ("+ProfileUtilities.summarizeSlicing(slicingL)+" / "+ProfileUtilities.summarizeSlicing(slicingR)+")");
// }
// }
// // todo: name
// }
// return ret;
//
// // TODO Auto-generated method stub
// return null;
}
use of org.hl7.fhir.r4b.model.Property in project org.hl7.fhir.core by hapifhir.
the class ValueSetComparer method renderCompose.
public XhtmlNode renderCompose(ValueSetComparison csc, String id, String prefix) throws FHIRException, IOException {
HierarchicalTableGenerator gen = new HierarchicalTableGenerator(Utilities.path("[tmp]", "comparison"), false);
TableModel model = gen.new TableModel(id, true);
model.setAlternating(true);
model.getTitles().add(gen.new Title(null, null, "Item", "The type of item being compared", null, 100));
model.getTitles().add(gen.new Title(null, null, "Property", "The system for the concept", null, 100, 2));
model.getTitles().add(gen.new Title(null, null, "Value", "The display for the concept", null, 200, 2));
model.getTitles().add(gen.new Title(null, null, "Comments", "Additional information about the comparison", null, 200));
for (StructuralMatch<Element> t : csc.getIncludes().getChildren()) {
addComposeRow(gen, model.getRows(), t, "include");
}
for (StructuralMatch<Element> t : csc.getExcludes().getChildren()) {
addComposeRow(gen, model.getRows(), t, "exclude");
}
return gen.generate(model, prefix, 0, null);
}
use of org.hl7.fhir.r4b.model.Property in project org.hl7.fhir.core by hapifhir.
the class ExtensionHelper method setExtension.
/**
* set the value of an extension on the element. if value == null, make sure it doesn't exist
*
* @param element - the element to act on. Can also be a backbone element
* @param modifier - whether this is a modifier. Note that this is a definitional property of the extension; don't alternate
* @param uri - the identifier for the extension
* @param value - the value of the extension. Delete if this is null
* @throws Exception - if the modifier logic is incorrect
*/
public static void setExtension(Element element, boolean modifier, String uri, DataType value) throws FHIRException {
if (value == null) {
// deleting the extension
if (element instanceof BackboneElement)
for (Extension e : ((BackboneElement) element).getModifierExtension()) {
if (uri.equals(e.getUrl()))
((BackboneElement) element).getModifierExtension().remove(e);
}
for (Extension e : element.getExtension()) {
if (uri.equals(e.getUrl()))
element.getExtension().remove(e);
}
} else {
// it would probably be easier to delete and then create, but this would re-order the extensions
// not that order matters, but we'll preserve it anyway
boolean found = false;
if (element instanceof BackboneElement)
for (Extension e : ((BackboneElement) element).getModifierExtension()) {
if (uri.equals(e.getUrl())) {
if (!modifier)
throw new FHIRException("Error adding extension \"" + uri + "\": found an existing modifier extension, and the extension is not marked as a modifier");
e.setValue(value);
found = true;
}
}
for (Extension e : element.getExtension()) {
if (uri.equals(e.getUrl())) {
if (modifier)
throw new FHIRException("Error adding extension \"" + uri + "\": found an existing extension, and the extension is marked as a modifier");
e.setValue(value);
found = true;
}
}
if (!found) {
Extension ex = new Extension().setUrl(uri).setValue(value);
if (modifier) {
if (!(element instanceof BackboneElement))
throw new FHIRException("Error adding extension \"" + uri + "\": extension is marked as a modifier, but element is not a backbone element");
((BackboneElement) element).getModifierExtension().add(ex);
} else {
element.getExtension().add(ex);
}
}
}
}
Aggregations