use of org.hl7.fhir.definitions.model.Compartment in project org.hl7.fhir.core by hapifhir.
the class CompartmentDefinitionRenderer method render.
public boolean render(XhtmlNode x, CompartmentDefinition cpd) throws FHIRFormatError, DefinitionException, IOException {
StringBuilder in = new StringBuilder();
StringBuilder out = new StringBuilder();
for (CompartmentDefinitionResourceComponent cc : cpd.getResource()) {
CommaSeparatedStringBuilder rules = new CommaSeparatedStringBuilder();
if (!cc.hasParam()) {
out.append(" <li><a href=\"").append(cc.getCode().toLowerCase()).append(".html\">").append(cc.getCode()).append("</a></li>\r\n");
} else if (!rules.equals("{def}")) {
for (StringType p : cc.getParam()) rules.append(p.asStringValue());
in.append(" <tr><td><a href=\"").append(cc.getCode().toLowerCase()).append(".html\">").append(cc.getCode()).append("</a></td><td>").append(rules.toString()).append("</td></tr>\r\n");
}
}
XhtmlNode xn;
xn = new XhtmlParser().parseFragment("<div><p>\r\nThe following resources may be in this compartment:\r\n</p>\r\n" + "<table class=\"grid\">\r\n" + " <tr><td><b>Resource</b></td><td><b>Inclusion Criteria</b></td></tr>\r\n" + in.toString() + "</table>\r\n" + "<p>\r\nA resource is in this compartment if the nominated search parameter (or chain) refers to the patient resource that defines the compartment.\r\n</p>\r\n" + "<p>\r\n\r\n</p>\r\n" + "<p>\r\nThe following resources are never in this compartment:\r\n</p>\r\n" + "<ul>\r\n" + out.toString() + "</ul></div>\r\n");
x.getChildNodes().addAll(xn.getChildNodes());
return true;
}
use of org.hl7.fhir.definitions.model.Compartment in project org.hl7.fhir.core by hapifhir.
the class CompartmentDefinitionRenderer method render.
public boolean render(XhtmlNode x, CompartmentDefinition cpd) throws FHIRFormatError, DefinitionException, IOException {
StringBuilder in = new StringBuilder();
StringBuilder out = new StringBuilder();
for (CompartmentDefinitionResourceComponent cc : cpd.getResource()) {
CommaSeparatedStringBuilder rules = new CommaSeparatedStringBuilder();
if (!cc.hasParam()) {
out.append(" <li><a href=\"").append(cc.getCode().toLowerCase()).append(".html\">").append(cc.getCode()).append("</a></li>\r\n");
} else if (!rules.equals("{def}")) {
for (StringType p : cc.getParam()) rules.append(p.asStringValue());
in.append(" <tr><td><a href=\"").append(cc.getCode().toLowerCase()).append(".html\">").append(cc.getCode()).append("</a></td><td>").append(rules.toString()).append("</td></tr>\r\n");
}
}
XhtmlNode xn;
xn = new XhtmlParser().parseFragment("<div><p>\r\nThe following resources may be in this compartment:\r\n</p>\r\n" + "<table class=\"grid\">\r\n" + " <tr><td><b>Resource</b></td><td><b>Inclusion Criteria</b></td></tr>\r\n" + in.toString() + "</table>\r\n" + "<p>\r\nA resource is in this compartment if the nominated search parameter (or chain) refers to the patient resource that defines the compartment.\r\n</p>\r\n" + "<p>\r\n\r\n</p>\r\n" + "<p>\r\nThe following resources are never in this compartment:\r\n</p>\r\n" + "<ul>\r\n" + out.toString() + "</ul></div>\r\n");
x.getChildNodes().addAll(xn.getChildNodes());
return true;
}
use of org.hl7.fhir.definitions.model.Compartment in project fhir-bridge by ehrbase.
the class SmartOnFhirAuthorizationInterceptor method addSmartOFPatientRules.
/**
* Allos read and write access to all Patients resources for a particular patient Id In FHIR
* terms, if the resource's Patient compartment matches the provided id, then read and write
* operations can take place.
*
* @param pSmartOnFhirPatientId The patient identifier a resource should have to be allowed for
* read or write access.
* @param rules A list of rules to add to. Rules based on the provided patient id will be added to
* this collection.
*/
private void addSmartOFPatientRules(String pSmartOnFhirPatientId, List<IAuthRule> rules) {
// no create rule -> should be done by keycloak registration at the moment
IdType sofId = new IdType(Patient.class.getSimpleName(), pSmartOnFhirPatientId);
rules.addAll(buildReadRule("rule_read_own_sof_patient_resource", Patient.class, Patient.class.getSimpleName(), sofId));
rules.addAll(buildWriteRule("rule_update_own_sof_patient_resource", Patient.class, Patient.class.getSimpleName(), sofId));
}
use of org.hl7.fhir.definitions.model.Compartment in project kindling by HL7.
the class ResourceValidator method check.
public void check(List<ValidationMessage> errors, String name, ResourceDefn rd) throws Exception {
for (String s : rd.getHints()) hint(errors, IssueType.INFORMATIONAL, rd.getName(), false, s);
rule(errors, IssueType.STRUCTURE, rd.getName(), !name.equals("Metadata"), "The name 'Metadata' is not a legal name for a resource");
rule(errors, IssueType.STRUCTURE, rd.getName(), !name.equals("History"), "The name 'History' is not a legal name for a resource");
rule(errors, IssueType.STRUCTURE, rd.getName(), !name.equals("Tag"), "The name 'Tag' is not a legal name for a resource");
rule(errors, IssueType.STRUCTURE, rd.getName(), !name.equals("Tags"), "The name 'Tags' is not a legal name for a resource");
rule(errors, IssueType.STRUCTURE, rd.getName(), !name.equals("MailBox"), "The name 'MailBox' is not a legal name for a resource");
rule(errors, IssueType.STRUCTURE, rd.getName(), !name.equals("Validation"), "The name 'Validation' is not a legal name for a resource");
rule(errors, IssueType.REQUIRED, rd.getName(), name.equals("Parameters") || translations.hasTranslation(name), "The name '" + name + "' is not found in the file translations.xml");
rule(errors, IssueType.STRUCTURE, rd.getName(), name.length() > 1 && Character.isUpperCase(name.charAt(0)), "Resource Name must start with an uppercase alpha character");
rule(errors, IssueType.STRUCTURE, rd.getName(), !Utilities.noString(rd.getFmmLevel()), "Resource must have a maturity level");
// too many downstream issues in the parsers, and it would only happen as a transient thing when designing the resources
rule(errors, IssueType.REQUIRED, rd.getName(), rd.getRoot().getElements().size() > 0, "A resource must have at least one element in it before the build can proceed");
// too many downstream issues in the parsers, and it would only happen as a transient thing when designing the resources
rule(errors, IssueType.REQUIRED, rd.getName(), rd.getWg() != null, "A resource must have a designated owner");
rule(errors, IssueType.REQUIRED, rd.getName(), !Utilities.noString(rd.getRoot().getW5()), "A resource must have a W5 category");
rd.getRoot().setMinCardinality(0);
rd.getRoot().setMaxCardinality(Integer.MAX_VALUE);
// pattern related rules
buildW5Mappings(rd.getRoot(), true);
if ((isWorkflowPattern(rd, "Event") || isWorkflowPattern(rd, "Request")) && hasPatient(rd)) {
rule(errors, IssueType.STRUCTURE, rd.getName(), rd.getSearchParams().containsKey("patient"), "An 'event' or 'request' resource must have a search parameter 'patient'");
}
if (suppressedwarning(errors, IssueType.REQUIRED, rd.getName(), hasW5Mappings(rd) || rd.getName().equals("Binary") || rd.getName().equals("OperationOutcome") || rd.getName().equals("Parameters"), "A resource must have w5 mappings")) {
String w5Order = listW5Elements(rd);
String w5CorrectOrder = listW5Correct(rd);
if (!w5Order.equals(w5CorrectOrder)) {
warning(errors, IssueType.REQUIRED, rd.getName(), false, "Resource elements are out of order. The correct order is '" + w5CorrectOrder + "' but the actual order is '" + w5Order + "'");
// System.out.println("Resource "+parent.getName()+": elements are out of order. The correct order is '"+w5CorrectOrder+"' but the actual order is '"+w5Order+"'");
}
if (!Utilities.noString(rd.getProposedOrder())) {
w5Order = listW5Elements(rd, rd.getProposedOrder());
if (!w5Order.equals(w5CorrectOrder)) {
rule(errors, IssueType.REQUIRED, rd.getName(), false, "Proposed Resource elements are out of order. The correct order is '" + w5CorrectOrder + "' but the proposed order is '" + w5Order + "'");
} else
System.out.println("Proposed order for " + rd.getName() + ": build order ok");
}
}
if (Utilities.noString(rd.getEnteredInErrorStatus()))
if (hasStatus(rd, "entered-in-error"))
rd.setEnteredInErrorStatus(".status = entered-in-error");
else if (hasStatus(rd, "retired"))
rd.setEnteredInErrorStatus(".status = retired");
else if (hasActivFalse(rd))
rd.setEnteredInErrorStatus(".active = false");
else
// too many downstream issues in the parsers, and it would only happen as a transient thing when designing the resources
warning(errors, IssueType.REQUIRED, rd.getName(), false, "A resource must have an 'entered in error' status");
String s = rd.getRoot().getMapping(Definitions.RIM_MAPPING);
hint(errors, IssueType.REQUIRED, rd.getName(), !Utilities.noString(s), "RIM Mapping is required");
for (Operation op : rd.getOperations()) {
warning(errors, IssueType.BUSINESSRULE, rd.getName() + ".$" + op.getName(), hasOpExample(op.getExamples(), false), "Operation must have an example request");
warning(errors, IssueType.BUSINESSRULE, rd.getName() + ".$" + op.getName(), hasOpExample(op.getExamples(), true), "Operation must have an example response");
}
List<String> vsWarns = new ArrayList<String>();
int vsWarnings = checkElement(errors, rd.getName(), rd.getRoot(), rd, null, s == null || !s.equalsIgnoreCase("n/a"), false, hasSummary(rd.getRoot()), vsWarns, true, rd.getStatus());
if (!resourceIsTechnical(name)) {
// these are exempt because identification is tightly managed
ElementDefn id = rd.getRoot().getElementByName(definitions, "identifier", true, false);
if (id == null)
warning(errors, IssueType.STRUCTURE, rd.getName(), false, "All resources should have an identifier");
else
rule(errors, IssueType.STRUCTURE, rd.getName(), id.typeCode().equals("Identifier"), "If a resource has an element named identifier, it must have a type 'Identifier'");
}
rule(errors, IssueType.STRUCTURE, rd.getName(), rd.getRoot().getElementByName(definitions, "text", true, false) == null, "Element named \"text\" not allowed");
rule(errors, IssueType.STRUCTURE, rd.getName(), rd.getRoot().getElementByName(definitions, "contained", true, false) == null, "Element named \"contained\" not allowed");
if (rd.getRoot().getElementByName(definitions, "subject", true, false) != null && rd.getRoot().getElementByName(definitions, "subject", true, false).typeCode().startsWith("Reference"))
rule(errors, IssueType.STRUCTURE, rd.getName(), rd.getSearchParams().containsKey("subject"), "A resource that contains a subject reference must have a search parameter 'subject'");
ElementDefn ped = rd.getRoot().getElementByName(definitions, "patient", true, false);
if (ped != null && ped.typeCode().startsWith("Reference")) {
SearchParameterDefn spd = rd.getSearchParams().get("patient");
if (rule(errors, IssueType.STRUCTURE, rd.getName(), spd != null, "A resource that contains a patient reference must have a search parameter 'patient'"))
rule(errors, IssueType.STRUCTURE, rd.getName(), (spd.getTargets().size() == 1 && spd.getTargets().contains("Patient")) || (ped.getTypes().get(0).getParams().size() == 1 && ped.getTypes().get(0).getParams().get(0).equals("Patient")), "A Patient search parameter must only refer to patient");
}
ElementDefn sed = rd.getRoot().getElementByName(definitions, "subject", true, false);
if (sed != null && sed.typeCode().startsWith("Reference") && sed.typeCode().contains("Patient"))
warning(errors, IssueType.STRUCTURE, rd.getName(), rd.getSearchParams().containsKey("patient"), "A resource that contains a subject that can be a patient reference must have a search parameter 'patient'");
if (rd.getRoot().getElementByName(definitions, "identifier", true, false) != null) {
warning(errors, IssueType.STRUCTURE, rd.getName(), rd.getSearchParams().containsKey("identifier"), "A resource that contains an identifier must have a search parameter 'identifier'");
}
if (rd.getRoot().getElementByName(definitions, "status", true, false) != null) {
// todo: change to a warning post STU3
hint(errors, IssueType.STRUCTURE, rd.getName(), rd.getSearchParams().containsKey("status"), "A resource that contains a status element must have a search parameter 'status'");
}
if (rd.getRoot().getElementByName(definitions, "url", true, false) != null) {
warning(errors, IssueType.STRUCTURE, rd.getName(), rd.getSearchParams().containsKey("url"), "A resource that contains a url element must have a search parameter 'url'");
}
checkSearchParams(errors, rd);
for (Operation op : rd.getOperations()) {
rule(errors, IssueType.STRUCTURE, rd.getName() + "/$" + op.getName(), !parentHasOp(rd.getRoot().typeCode(), op.getName()), "Duplicate Operation Name $" + op.getName() + " on " + rd.getName());
}
for (Compartment c : definitions.getCompartments()) {
if (rule(errors, IssueType.STRUCTURE, rd.getName(), name.equals("Parameters") || c.getResources().containsKey(rd), "Resource not entered in resource map for compartment '" + c.getTitle() + "' (compartments.xml)")) {
String param = c.getResources().get(rd);
if (!Utilities.noString(param)) {
// rule(errors, IssueType.STRUCTURE, parent.getName(), param.equals("{def}") || parent.getSearchParams().containsKey(c.getName()), "Resource "+parent.getName()+" in compartment " +c.getName()+" must have a search parameter named "+c.getName().toLowerCase()+")");
for (String p : param.split("\\|")) {
String pn = p.trim();
if (pn.contains("."))
pn = pn.substring(0, pn.indexOf("."));
rule(errors, IssueType.STRUCTURE, rd.getName(), Utilities.noString(pn) || pn.equals("{def}") || rd.getSearchParams().containsKey(pn), "Resource " + rd.getName() + " in compartment " + c.getName() + ": parameter " + param + " was not found (" + pn + ")");
}
}
}
}
// Remove suppressed messages
List<ValidationMessage> suppressed = new ArrayList<ValidationMessage>();
for (ValidationMessage em : errors) {
if (isSuppressedMessage(em.getDisplay())) {
suppressed.add(em);
}
}
errors.removeAll(suppressed);
// last check: if maturity level is
int warnings = 0;
int hints = 0;
for (ValidationMessage em : errors) {
if (em.getLevel() == IssueSeverity.WARNING)
warnings++;
else if (em.getLevel() == IssueSeverity.INFORMATION)
hints++;
}
boolean ok = warnings == 0 || "0".equals(rd.getFmmLevel());
if (rule(errors, IssueType.STRUCTURE, rd.getName(), ok, "Resource " + rd.getName() + " (FMM=" + rd.getFmmLevel() + ") cannot have an FMM level >1 (" + rd.getFmmLevel() + ") if it has warnings"))
rule(errors, IssueType.STRUCTURE, rd.getName(), vsWarnings == 0 || "0".equals(rd.getFmmLevel()), "Resource " + rd.getName() + " (FMM=" + rd.getFmmLevel() + ") cannot have an FMM level >1 (" + rd.getFmmLevel() + ") if it has linked value set warnings (" + vsWarns.toString() + ")");
ok = hints == 0 || Integer.parseInt(rd.getFmmLevel()) < 3;
rule(errors, IssueType.STRUCTURE, rd.getName(), ok, "Resource " + rd.getName() + " (FMM=" + rd.getFmmLevel() + ") cannot have an FMM level >2 (" + rd.getFmmLevel() + ") if it has informational hints");
// if (isInterface(rd.getRoot().typeCode())) {
// checkInterface(errors, rd, definitions.getBaseResources().get(rd.getRoot().typeCode()));
// }
}
use of org.hl7.fhir.definitions.model.Compartment in project kindling by HL7.
the class PageProcessor method compartmentlist.
private String compartmentlist() {
StringBuilder b = new StringBuilder();
b.append("<table class=\"grid\">\r\n");
b.append(" <tr><td><b>Title</b></td><td><b>Description</b></td><td><b>Identity</b></td><td><b>Membership</b></td></tr>\r\n");
for (Compartment c : definitions.getCompartments()) {
b.append(" <tr><td><a href=\"compartmentdefinition-").append(c.getName().toLowerCase()).append(".html\">").append(c.getTitle()).append("</a></td><td>").append(Utilities.escapeXml(c.getDescription())).append("</td>").append("<td>").append(Utilities.escapeXml(c.getIdentity())).append("</td><td>").append(Utilities.escapeXml(c.getMembership())).append("</td></tr>\r\n");
}
b.append("</table>\r\n");
return b.toString();
}
Aggregations