001package org.hl7.fhir.r5.utils; 002 003import java.util.ArrayList; 004 005/* 006 Copyright (c) 2011+, HL7, Inc. 007 All rights reserved. 008 009 Redistribution and use in source and binary forms, with or without modification, 010 are permitted provided that the following conditions are met: 011 012 * Redistributions of source code must retain the above copyright notice, this 013 list of conditions and the following disclaimer. 014 * Redistributions in binary form must reproduce the above copyright notice, 015 this list of conditions and the following disclaimer in the documentation 016 and/or other materials provided with the distribution. 017 * Neither the name of HL7 nor the names of its contributors may be used to 018 endorse or promote products derived from this software without specific 019 prior written permission. 020 021 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 022 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 023 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 024 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 025 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 026 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 027 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 028 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 029 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 030 POSSIBILITY OF SUCH DAMAGE. 031 032 */ 033 034 035import java.util.List; 036import java.util.Locale; 037import java.util.Map; 038import java.util.Set; 039 040import org.hl7.fhir.r5.model.Base; 041import org.hl7.fhir.r5.model.Bundle; 042import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent; 043import org.hl7.fhir.r5.model.Bundle.BundleLinkComponent; 044import org.hl7.fhir.r5.model.CanonicalResource; 045import org.hl7.fhir.r5.model.CodeableConcept; 046import org.hl7.fhir.r5.model.Coding; 047import org.hl7.fhir.r5.model.ContactPoint; 048import org.hl7.fhir.r5.model.ContactPoint.ContactPointSystem; 049import org.hl7.fhir.r5.model.DataType; 050import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent; 051import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent; 052import org.hl7.fhir.r5.model.Meta; 053import org.hl7.fhir.r5.model.OperationOutcome; 054import org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity; 055import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent; 056import org.hl7.fhir.r5.model.Property; 057import org.hl7.fhir.r5.model.Reference; 058import org.hl7.fhir.r5.model.Resource; 059import org.hl7.fhir.r5.model.ResourceType; 060import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; 061import org.hl7.fhir.utilities.Utilities; 062import org.hl7.fhir.utilities.xhtml.XhtmlComposer; 063 064/** 065 * Decoration utilities for various resource types 066 * @author Grahame 067 * 068 */ 069public class ResourceUtilities { 070 071 public final static String FHIR_LANGUAGE = "urn:ietf:bcp:47"; 072 private static JurisdictionLocales jl = new JurisdictionLocales(); 073 074 public static boolean isAnError(OperationOutcome error) { 075 for (OperationOutcomeIssueComponent t : error.getIssue()) 076 if (t.getSeverity() == IssueSeverity.ERROR) 077 return true; 078 else if (t.getSeverity() == IssueSeverity.FATAL) 079 return true; 080 return false; 081 } 082 083 public static String getErrorDescription(OperationOutcome error) { 084 if (error.hasText() && error.getText().hasDiv()) { 085 return new XhtmlComposer(XhtmlComposer.XML).composePlainText(error.getText().getDiv()); 086 } 087 088 StringBuilder b = new StringBuilder(); 089 for (OperationOutcomeIssueComponent t : error.getIssue()) { 090 if (t.getSeverity() == IssueSeverity.ERROR) { 091 b.append("Error:" +t.getDetails()+"\r\n"); 092 } else if (t.getSeverity() == IssueSeverity.FATAL) { 093 b.append("Fatal:" +t.getDetails()+"\r\n"); 094 } else if (t.getSeverity() == IssueSeverity.WARNING) { 095 b.append("Warning:" +t.getDetails()+"\r\n"); 096 } else if (t.getSeverity() == IssueSeverity.INFORMATION) { 097 b.append("Information:" +t.getDetails()+"\r\n"); 098 } 099 } 100 return b.toString(); 101 } 102 103 public static Resource getById(Bundle feed, ResourceType type, String reference) { 104 for (BundleEntryComponent item : feed.getEntry()) { 105 if (item.getResource().getId().equals(reference) && item.getResource().getResourceType() == type) 106 return item.getResource(); 107 } 108 return null; 109 } 110 111 public static BundleEntryComponent getEntryById(Bundle feed, ResourceType type, String reference) { 112 for (BundleEntryComponent item : feed.getEntry()) { 113 if (item.getResource().getId().equals(reference) && item.getResource().getResourceType() == type) 114 return item; 115 } 116 return null; 117 } 118 119 public static String getLink(Bundle feed, String rel) { 120 for (BundleLinkComponent link : feed.getLink()) { 121 if (link.getRelation().equals(rel)) 122 return link.getUrl(); 123 } 124 return null; 125 } 126 127 public static Meta meta(Resource resource) { 128 if (!resource.hasMeta()) 129 resource.setMeta(new Meta()); 130 return resource.getMeta(); 131 } 132 133 public static Locale getLocale(CanonicalResource cr) { 134 return getLocale(cr.getLanguage(), cr.getJurisdiction()); 135 } 136 137 public static Locale getLocale(String lang, List<CodeableConcept> jurisdictions) { 138 if (lang != null && lang.contains("-")) { 139 return new Locale(lang); 140 } 141 for (CodeableConcept cc : jurisdictions) { 142 Locale locale = getLocale(lang, cc); 143 if (locale != null) { 144 return locale; 145 } 146 } 147 return null; 148 } 149 150 151 private static Locale getLocale(String lang, CodeableConcept cc) { 152 if (cc.hasCoding("http://unstats.un.org/unsd/methods/m49/m49.htm", "001")) { 153 return new Locale("en-US"); 154 } 155 String c = cc.getCode("urn:iso:std:iso:3166"); 156 if (c == null) { 157 return null; 158 } 159 String l = jl.get(c); 160 if (l == null) { 161 return null; 162 } else if (lang != null) { 163 return new Locale(lang+"-"+l.substring(l.indexOf("-")+1)); 164 } else { 165 return new Locale(l); 166 } 167 } 168 169 public static String listUrls(List<? extends CanonicalResource> list) { 170 CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); 171 for (CanonicalResource t : list) { 172 b.append(t.getVUrl()); 173 } 174 return b.toString(); 175 } 176 177 public static String listStrings(Set<String> set) { 178 List<String> list = Utilities.sorted(set); 179 CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); 180 for (String s : list) { 181 b.append(s); 182 } 183 return b.toString(); 184 } 185 186 public static boolean hasURL(String uri, Resource src) { 187 for (Property p : src.children()) { 188 if (hasURL(uri, p)) { 189 return true; 190 } 191 } 192 return false; 193 } 194 195 private static boolean hasURL(String uri, Property p) { 196 for (Base b : p.getValues()) { 197 if (b.isPrimitive()) { 198 return uri.equals(b.primitiveValue()); 199 } else { 200 for (Property c : b.children()) { 201 if (hasURL(uri, c)) { 202 return true; 203 } 204 } 205 } 206 } 207 return false; 208 } 209}